Moved credential manager to libstrongswan
authorMartin Willi <martin@revosec.ch>
Mon, 5 Jul 2010 09:54:25 +0000 (11:54 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 13 Jul 2010 08:26:07 +0000 (10:26 +0200)
59 files changed:
src/libcharon/Android.mk
src/libcharon/Makefile.am
src/libcharon/config/auth_cfg.c [deleted file]
src/libcharon/config/auth_cfg.h [deleted file]
src/libcharon/config/peer_cfg.h
src/libcharon/credentials/credential_manager.c [deleted file]
src/libcharon/credentials/credential_manager.h [deleted file]
src/libcharon/credentials/credential_set.h [deleted file]
src/libcharon/credentials/sets/auth_cfg_wrapper.c [deleted file]
src/libcharon/credentials/sets/auth_cfg_wrapper.h [deleted file]
src/libcharon/credentials/sets/cert_cache.c [deleted file]
src/libcharon/credentials/sets/cert_cache.h [deleted file]
src/libcharon/credentials/sets/ocsp_response_wrapper.c [deleted file]
src/libcharon/credentials/sets/ocsp_response_wrapper.h [deleted file]
src/libcharon/daemon.c
src/libcharon/daemon.h
src/libcharon/plugins/android/android_plugin.c
src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c
src/libcharon/plugins/eap_gtc/eap_gtc.c
src/libcharon/plugins/eap_md5/eap_md5.c
src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
src/libcharon/plugins/ha/ha_tunnel.c
src/libcharon/plugins/load_tester/load_tester_plugin.c
src/libcharon/plugins/medcli/medcli_plugin.c
src/libcharon/plugins/medsrv/medsrv_plugin.c
src/libcharon/plugins/nm/nm_plugin.c
src/libcharon/plugins/sql/sql_plugin.c
src/libcharon/plugins/stroke/stroke_ca.c
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/stroke/stroke_socket.c
src/libcharon/plugins/uci/uci_plugin.c
src/libcharon/plugins/unit_tester/tests/test_auth_info.c
src/libcharon/plugins/unit_tester/tests/test_med_db.c
src/libcharon/sa/authenticators/authenticator.c
src/libcharon/sa/authenticators/authenticator.h
src/libcharon/sa/authenticators/eap/eap_method.c
src/libcharon/sa/authenticators/eap/eap_method.h
src/libcharon/sa/authenticators/psk_authenticator.c
src/libcharon/sa/authenticators/pubkey_authenticator.c
src/libcharon/sa/ike_sa.h
src/libcharon/sa/tasks/ike_cert_post.c
src/libcharon/sa/tasks/ike_cert_pre.c
src/libstrongswan/Android.mk
src/libstrongswan/Makefile.am
src/libstrongswan/credentials/auth_cfg.c [new file with mode: 0644]
src/libstrongswan/credentials/auth_cfg.h [new file with mode: 0644]
src/libstrongswan/credentials/credential_manager.c [new file with mode: 0644]
src/libstrongswan/credentials/credential_manager.h [new file with mode: 0644]
src/libstrongswan/credentials/credential_set.h [new file with mode: 0644]
src/libstrongswan/credentials/keys/private_key.h
src/libstrongswan/credentials/sets/auth_cfg_wrapper.c [new file with mode: 0644]
src/libstrongswan/credentials/sets/auth_cfg_wrapper.h [new file with mode: 0644]
src/libstrongswan/credentials/sets/cert_cache.c [new file with mode: 0644]
src/libstrongswan/credentials/sets/cert_cache.h [new file with mode: 0644]
src/libstrongswan/credentials/sets/ocsp_response_wrapper.c [new file with mode: 0644]
src/libstrongswan/credentials/sets/ocsp_response_wrapper.h [new file with mode: 0644]
src/libstrongswan/library.c
src/libstrongswan/library.h

index 1c47082..3297654 100644 (file)
@@ -12,7 +12,6 @@ config/child_cfg.c config/child_cfg.h \
 config/ike_cfg.c config/ike_cfg.h \
 config/peer_cfg.c config/peer_cfg.h \
 config/proposal.c config/proposal.h \
-config/auth_cfg.c config/auth_cfg.h \
 control/controller.c control/controller.h \
 daemon.c daemon.h \
 encoding/generator.c encoding/generator.h \
@@ -95,12 +94,7 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
 sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
 sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
 sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
-sa/tasks/task.c sa/tasks/task.h \
-credentials/credential_manager.c credentials/credential_manager.h \
-credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
-credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
-credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
-credentials/credential_set.h
+sa/tasks/task.c sa/tasks/task.h
 
 # adding the plugin source files
 
index 108609f..d9540e6 100644 (file)
@@ -10,7 +10,6 @@ config/child_cfg.c config/child_cfg.h \
 config/ike_cfg.c config/ike_cfg.h \
 config/peer_cfg.c config/peer_cfg.h \
 config/proposal.c config/proposal.h \
-config/auth_cfg.c config/auth_cfg.h \
 control/controller.c control/controller.h \
 daemon.c daemon.h \
 encoding/generator.c encoding/generator.h \
@@ -93,12 +92,7 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
 sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
 sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
 sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
-sa/tasks/task.c sa/tasks/task.h \
-credentials/credential_manager.c credentials/credential_manager.h \
-credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
-credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
-credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
-credentials/credential_set.h
+sa/tasks/task.c sa/tasks/task.h
 
 daemon.lo :            $(top_builddir)/config.status
 
diff --git a/src/libcharon/config/auth_cfg.c b/src/libcharon/config/auth_cfg.c
deleted file mode 100644 (file)
index c34bdaf..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * 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 "auth_cfg.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <credentials/certificates/certificate.h>
-
-ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
-       "RULE_IDENTITY",
-       "RULE_AUTH_CLASS",
-       "RULE_EAP_IDENTITY",
-       "RULE_EAP_TYPE",
-       "RULE_EAP_VENDOR",
-       "RULE_CA_CERT",
-       "RULE_IM_CERT",
-       "RULE_SUBJECT_CERT",
-       "RULE_CRL_VALIDATION",
-       "RULE_OCSP_VALIDATION",
-       "RULE_GROUP",
-       "HELPER_IM_CERT",
-       "HELPER_SUBJECT_CERT",
-       "HELPER_IM_HASH_URL",
-       "HELPER_SUBJECT_HASH_URL",
-);
-
-typedef struct private_auth_cfg_t private_auth_cfg_t;
-
-/**
- * private data of item_set
- */
-struct private_auth_cfg_t {
-
-       /**
-        * public functions
-        */
-       auth_cfg_t public;
-
-       /**
-        * list of entry_t
-        */
-       linked_list_t *entries;
-};
-
-typedef struct entry_t entry_t;
-
-struct entry_t {
-       /** rule type */
-       auth_rule_t type;
-       /** associated value */
-       void *value;
-};
-
-/**
- * enumerator for auth_cfg_t.create_enumerator()
- */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** inner enumerator from linked_list_t */
-       enumerator_t *inner;
-       /** current entry */
-       entry_t *current;
-} entry_enumerator_t;
-
-/**
- * enumerate function for item_enumerator_t
- */
-static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
-{
-       entry_t *entry;
-
-       if (this->inner->enumerate(this->inner, &entry))
-       {
-               this->current = entry;
-               *type = entry->type;
-               *value = entry->value;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * destroy function for item_enumerator_t
- */
-static void entry_enumerator_destroy(entry_enumerator_t *this)
-{
-       this->inner->destroy(this->inner);
-       free(this);
-}
-
-/**
- * Implementation of auth_cfg_t.create_enumerator.
- */
-static enumerator_t* create_enumerator(private_auth_cfg_t *this)
-{
-       entry_enumerator_t *enumerator;
-
-       enumerator = malloc_thing(entry_enumerator_t);
-       enumerator->inner = this->entries->create_enumerator(this->entries);
-       enumerator->public.enumerate = (void*)enumerate;
-       enumerator->public.destroy = (void*)entry_enumerator_destroy;
-       enumerator->current = NULL;
-       return &enumerator->public;
-}
-
-/**
- * Destroy the value associated with an entry
- */
-static void destroy_entry_value(entry_t *entry)
-{
-       switch (entry->type)
-       {
-               case AUTH_RULE_IDENTITY:
-               case AUTH_RULE_EAP_IDENTITY:
-               case AUTH_RULE_GROUP:
-               {
-                       identification_t *id = (identification_t*)entry->value;
-                       id->destroy(id);
-                       break;
-               }
-               case AUTH_RULE_CA_CERT:
-               case AUTH_RULE_IM_CERT:
-               case AUTH_RULE_SUBJECT_CERT:
-               case AUTH_HELPER_IM_CERT:
-               case AUTH_HELPER_SUBJECT_CERT:
-               {
-                       certificate_t *cert = (certificate_t*)entry->value;
-                       cert->destroy(cert);
-                       break;
-               }
-               case AUTH_HELPER_IM_HASH_URL:
-               case AUTH_HELPER_SUBJECT_HASH_URL:
-               {
-                       free(entry->value);
-                       break;
-               }
-               case AUTH_RULE_AUTH_CLASS:
-               case AUTH_RULE_EAP_TYPE:
-               case AUTH_RULE_EAP_VENDOR:
-               case AUTH_RULE_CRL_VALIDATION:
-               case AUTH_RULE_OCSP_VALIDATION:
-                       break;
-       }
-}
-
-/**
- * Implementation of auth_cfg_t.replace.
- */
-static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
-                                       auth_rule_t type, ...)
-{
-       if (enumerator->current)
-       {
-               va_list args;
-
-               va_start(args, type);
-
-               destroy_entry_value(enumerator->current);
-               enumerator->current->type = type;
-               switch (type)
-               {
-                       case AUTH_RULE_AUTH_CLASS:
-                       case AUTH_RULE_EAP_TYPE:
-                       case AUTH_RULE_EAP_VENDOR:
-                       case AUTH_RULE_CRL_VALIDATION:
-                       case AUTH_RULE_OCSP_VALIDATION:
-                               /* integer type */
-                               enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
-                               break;
-                       case AUTH_RULE_IDENTITY:
-                       case AUTH_RULE_EAP_IDENTITY:
-                       case AUTH_RULE_GROUP:
-                       case AUTH_RULE_CA_CERT:
-                       case AUTH_RULE_IM_CERT:
-                       case AUTH_RULE_SUBJECT_CERT:
-                       case AUTH_HELPER_IM_CERT:
-                       case AUTH_HELPER_SUBJECT_CERT:
-                       case AUTH_HELPER_IM_HASH_URL:
-                       case AUTH_HELPER_SUBJECT_HASH_URL:
-                               /* pointer type */
-                               enumerator->current->value = va_arg(args, void*);
-                               break;
-               }
-               va_end(args);
-       }
-}
-
-/**
- * Implementation of auth_cfg_t.get.
- */
-static void* get(private_auth_cfg_t *this, auth_rule_t type)
-{
-       enumerator_t *enumerator;
-       void *current_value, *best_value = NULL;
-       auth_rule_t current_type;
-       bool found = FALSE;
-
-       enumerator = create_enumerator(this);
-       while (enumerator->enumerate(enumerator, &current_type, &current_value))
-       {
-               if (type == current_type)
-               {
-                       if (type == AUTH_RULE_CRL_VALIDATION ||
-                               type == AUTH_RULE_OCSP_VALIDATION)
-                       {       /* for CRL/OCSP validation, always get() the highest value */
-                               if (!found || current_value > best_value)
-                               {
-                                       best_value = current_value;
-                               }
-                               found = TRUE;
-                               continue;
-                       }
-                       best_value = current_value;
-                       found = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       if (found)
-       {
-               return best_value;
-       }
-       switch (type)
-       {
-               /* use some sane defaults if we don't find an entry */
-               case AUTH_RULE_AUTH_CLASS:
-                       return (void*)AUTH_CLASS_ANY;
-               case AUTH_RULE_EAP_TYPE:
-                       return (void*)EAP_NAK;
-               case AUTH_RULE_EAP_VENDOR:
-                       return (void*)0;
-               case AUTH_RULE_CRL_VALIDATION:
-               case AUTH_RULE_OCSP_VALIDATION:
-                       return (void*)VALIDATION_FAILED;
-               case AUTH_RULE_IDENTITY:
-               case AUTH_RULE_EAP_IDENTITY:
-               case AUTH_RULE_GROUP:
-               case AUTH_RULE_CA_CERT:
-               case AUTH_RULE_IM_CERT:
-               case AUTH_RULE_SUBJECT_CERT:
-               case AUTH_HELPER_IM_CERT:
-               case AUTH_HELPER_SUBJECT_CERT:
-               case AUTH_HELPER_IM_HASH_URL:
-               case AUTH_HELPER_SUBJECT_HASH_URL:
-               default:
-                       return NULL;
-       }
-}
-
-/**
- * Implementation of auth_cfg_t.add.
- */
-static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
-{
-       entry_t *entry = malloc_thing(entry_t);
-       va_list args;
-
-       va_start(args, type);
-       entry->type = type;
-       switch (type)
-       {
-               case AUTH_RULE_AUTH_CLASS:
-               case AUTH_RULE_EAP_TYPE:
-               case AUTH_RULE_EAP_VENDOR:
-               case AUTH_RULE_CRL_VALIDATION:
-               case AUTH_RULE_OCSP_VALIDATION:
-                       /* integer type */
-                       entry->value = (void*)(uintptr_t)va_arg(args, u_int);
-                       break;
-               case AUTH_RULE_IDENTITY:
-               case AUTH_RULE_EAP_IDENTITY:
-               case AUTH_RULE_GROUP:
-               case AUTH_RULE_CA_CERT:
-               case AUTH_RULE_IM_CERT:
-               case AUTH_RULE_SUBJECT_CERT:
-               case AUTH_HELPER_IM_CERT:
-               case AUTH_HELPER_SUBJECT_CERT:
-               case AUTH_HELPER_IM_HASH_URL:
-               case AUTH_HELPER_SUBJECT_HASH_URL:
-                       /* pointer type */
-                       entry->value = va_arg(args, void*);
-                       break;
-       }
-       va_end(args);
-       this->entries->insert_last(this->entries, entry);
-}
-
-/**
- * Implementation of auth_cfg_t.complies.
- */
-static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
-                                        bool log_error)
-{
-       enumerator_t *e1, *e2;
-       bool success = TRUE, has_group = FALSE, group_match = FALSE;
-       auth_rule_t t1, t2;
-       void *value;
-
-       e1 = constraints->create_enumerator(constraints);
-       while (e1->enumerate(e1, &t1, &value))
-       {
-               switch (t1)
-               {
-                       case AUTH_RULE_CA_CERT:
-                       case AUTH_RULE_IM_CERT:
-                       {
-                               certificate_t *c1, *c2;
-
-                               c1 = (certificate_t*)value;
-
-                               success = FALSE;
-                               e2 = create_enumerator(this);
-                               while (e2->enumerate(e2, &t2, &c2))
-                               {
-                                       if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
-                                               c1->equals(c1, c2))
-                                       {
-                                               success = TRUE;
-                                       }
-                               }
-                               e2->destroy(e2);
-                               if (!success && log_error)
-                               {
-                                       DBG1(DBG_CFG, "constraint check failed: peer not "
-                                                "authenticated by CA '%Y'.", c1->get_subject(c1));
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_SUBJECT_CERT:
-                       {
-                               certificate_t *c1, *c2;
-
-                               c1 = (certificate_t*)value;
-                               c2 = get(this, AUTH_RULE_SUBJECT_CERT);
-                               if (!c2 || !c1->equals(c1, c2))
-                               {
-                                       success = FALSE;
-                                       if (log_error)
-                                       {
-                                               DBG1(DBG_CFG, "constraint check failed: peer not "
-                                                        "authenticated with peer cert '%Y'.",
-                                                        c1->get_subject(c1));
-                                       }
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_CRL_VALIDATION:
-                       case AUTH_RULE_OCSP_VALIDATION:
-                       {
-                               cert_validation_t validated, required;
-
-                               required = (uintptr_t)value;
-                               validated = (uintptr_t)get(this, t1);
-                               switch (required)
-                               {
-                                       case VALIDATION_FAILED:
-                                               /* no constraint */
-                                               break;
-                                       case VALIDATION_SKIPPED:
-                                               if (validated == VALIDATION_SKIPPED)
-                                               {
-                                                       break;
-                                               }
-                                               /* FALL */
-                                       case VALIDATION_GOOD:
-                                               if (validated == VALIDATION_GOOD)
-                                               {
-                                                       break;
-                                               }
-                                               /* FALL */
-                                       default:
-                                               success = FALSE;
-                                               if (log_error)
-                                               {
-                                                       DBG1(DBG_CFG, "constraint check failed: %N is %N, "
-                                                                "but requires at least %N", auth_rule_names,
-                                                                t1, cert_validation_names, validated,
-                                                                cert_validation_names, required);
-                                               }
-                                               break;
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_IDENTITY:
-                       case AUTH_RULE_EAP_IDENTITY:
-                       {
-                               identification_t *id1, *id2;
-
-                               id1 = (identification_t*)value;
-                               id2 = get(this, t1);
-                               if (!id2 || !id2->matches(id2, id1))
-                               {
-                                       success = FALSE;
-                                       if (log_error)
-                                       {
-                                               DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
-                                                        " required ", t1 == AUTH_RULE_IDENTITY ? "" :
-                                                        "EAP ", id1);
-                                       }
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_AUTH_CLASS:
-                       {
-                               if ((uintptr_t)value != AUTH_CLASS_ANY &&
-                                       (uintptr_t)value != (uintptr_t)get(this, t1))
-                               {
-                                       success = FALSE;
-                                       if (log_error)
-                                       {
-                                               DBG1(DBG_CFG, "constraint requires %N authentication, "
-                                                        "but %N was used", auth_class_names, (uintptr_t)value,
-                                                        auth_class_names, (uintptr_t)get(this, t1));
-                                       }
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_EAP_TYPE:
-                       {
-                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
-                               {
-                                       success = FALSE;
-                                       if (log_error)
-                                       {
-                                               DBG1(DBG_CFG, "constraint requires %N, "
-                                                        "but %N was used", eap_type_names, (uintptr_t)value,
-                                                        eap_type_names,  (uintptr_t)get(this, t1));
-                                       }
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_EAP_VENDOR:
-                       {
-                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
-                               {
-                                       success = FALSE;
-                                       if (log_error)
-                                       {
-                                               DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
-                                                        "but %d was used", (uintptr_t)value,
-                                                        (uintptr_t)get(this, t1));
-                                       }
-                               }
-                               break;
-                       }
-                       case AUTH_RULE_GROUP:
-                       {
-                               identification_t *id1, *id2;
-
-                               /* for groups, a match of a single group is sufficient */
-                               has_group = TRUE;
-                               id1 = (identification_t*)value;
-                               e2 = create_enumerator(this);
-                               while (e2->enumerate(e2, &t2, &id2))
-                               {
-                                       if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1))
-                                       {
-                                               group_match = TRUE;
-                                       }
-                               }
-                               e2->destroy(e2);
-                               break;
-                       }
-                       case AUTH_HELPER_IM_CERT:
-                       case AUTH_HELPER_SUBJECT_CERT:
-                       case AUTH_HELPER_IM_HASH_URL:
-                       case AUTH_HELPER_SUBJECT_HASH_URL:
-                               /* skip helpers */
-                               continue;
-               }
-               if (!success)
-               {
-                       break;
-               }
-       }
-       e1->destroy(e1);
-
-       if (has_group && !group_match)
-       {
-               if (log_error)
-               {
-                       DBG1(DBG_CFG, "constraint check failed: group membership required");
-               }
-               return FALSE;
-       }
-       return success;
-}
-
-/**
- * Implementation of auth_cfg_t.merge.
- */
-static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
-{
-       if (!other)
-       {       /* nothing to merge */
-               return;
-       }
-       if (copy)
-       {
-               enumerator_t *enumerator;
-               auth_rule_t type;
-               void *value;
-
-               enumerator = create_enumerator(other);
-               while (enumerator->enumerate(enumerator, &type, &value))
-               {
-                       switch (type)
-                       {
-                               case AUTH_RULE_CA_CERT:
-                               case AUTH_RULE_IM_CERT:
-                               case AUTH_RULE_SUBJECT_CERT:
-                               case AUTH_HELPER_IM_CERT:
-                               case AUTH_HELPER_SUBJECT_CERT:
-                               {
-                                       certificate_t *cert = (certificate_t*)value;
-
-                                       add(this, type, cert->get_ref(cert));
-                                       break;
-                               }
-                               case AUTH_RULE_CRL_VALIDATION:
-                               case AUTH_RULE_OCSP_VALIDATION:
-                               case AUTH_RULE_AUTH_CLASS:
-                               case AUTH_RULE_EAP_TYPE:
-                               case AUTH_RULE_EAP_VENDOR:
-                               {
-                                       add(this, type, (uintptr_t)value);
-                                       break;
-                               }
-                               case AUTH_RULE_IDENTITY:
-                               case AUTH_RULE_EAP_IDENTITY:
-                               case AUTH_RULE_GROUP:
-                               {
-                                       identification_t *id = (identification_t*)value;
-
-                                       add(this, type, id->clone(id));
-                                       break;
-                               }
-                               case AUTH_HELPER_IM_HASH_URL:
-                               case AUTH_HELPER_SUBJECT_HASH_URL:
-                               {
-                                       add(this, type, strdup((char*)value));
-                                       break;
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       else
-       {
-               entry_t *entry;
-
-               while (other->entries->remove_first(other->entries,
-                                                                                       (void**)&entry) == SUCCESS)
-               {
-                       this->entries->insert_last(this->entries, entry);
-               }
-       }
-}
-
-/**
- * Implementation of auth_cfg_t.equals.
- */
-static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
-{
-       enumerator_t *e1, *e2;
-       entry_t *i1, *i2;
-       bool equal = TRUE, found;
-
-       if (this->entries->get_count(this->entries) !=
-               other->entries->get_count(other->entries))
-       {
-               return FALSE;
-       }
-       e1 = this->entries->create_enumerator(this->entries);
-       while (e1->enumerate(e1, &i1))
-       {
-               found = FALSE;
-               e2 = other->entries->create_enumerator(other->entries);
-               while (e2->enumerate(e2, &i2))
-               {
-                       if (i1->type == i2->type)
-                       {
-                               switch (i1->type)
-                               {
-                                       case AUTH_RULE_AUTH_CLASS:
-                                       case AUTH_RULE_EAP_TYPE:
-                                       case AUTH_RULE_EAP_VENDOR:
-                                       case AUTH_RULE_CRL_VALIDATION:
-                                       case AUTH_RULE_OCSP_VALIDATION:
-                                       {
-                                               if (i1->value == i2->value)
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTH_RULE_CA_CERT:
-                                       case AUTH_RULE_IM_CERT:
-                                       case AUTH_RULE_SUBJECT_CERT:
-                                       case AUTH_HELPER_IM_CERT:
-                                       case AUTH_HELPER_SUBJECT_CERT:
-                                       {
-                                               certificate_t *c1, *c2;
-
-                                               c1 = (certificate_t*)i1->value;
-                                               c2 = (certificate_t*)i2->value;
-
-                                               if (c1->equals(c1, c2))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTH_RULE_IDENTITY:
-                                       case AUTH_RULE_EAP_IDENTITY:
-                                       case AUTH_RULE_GROUP:
-                                       {
-                                               identification_t *id1, *id2;
-
-                                               id1 = (identification_t*)i1->value;
-                                               id2 = (identification_t*)i2->value;
-
-                                               if (id1->equals(id1, id2))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTH_HELPER_IM_HASH_URL:
-                                       case AUTH_HELPER_SUBJECT_HASH_URL:
-                                       {
-                                               if (streq(i1->value, i2->value))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                               }
-                               break;
-                       }
-               }
-               e2->destroy(e2);
-               if (!found)
-               {
-                       equal = FALSE;
-                       break;
-               }
-       }
-       e1->destroy(e1);
-       return equal;
-}
-
-/**
- * Implementation of auth_cfg_t.purge
- */
-static void purge(private_auth_cfg_t *this, bool keep_ca)
-{
-       entry_t *entry;
-       linked_list_t *cas;
-
-       cas = linked_list_create();
-       while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
-       {
-               if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
-               {
-                       cas->insert_first(cas, entry);
-               }
-               else
-               {
-                       destroy_entry_value(entry);
-                       free(entry);
-               }
-       }
-       while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
-       {
-               this->entries->insert_first(this->entries, entry);
-       }
-       cas->destroy(cas);
-}
-
-/**
- * Implementation of auth_cfg_t.clone
- */
-static auth_cfg_t* clone_(private_auth_cfg_t *this)
-{
-       enumerator_t *enumerator;
-       auth_cfg_t *clone;
-       entry_t *entry;
-
-       clone = auth_cfg_create();
-       enumerator = this->entries->create_enumerator(this->entries);
-       while (enumerator->enumerate(enumerator, &entry))
-       {
-               switch (entry->type)
-               {
-                       case AUTH_RULE_IDENTITY:
-                       case AUTH_RULE_EAP_IDENTITY:
-                       case AUTH_RULE_GROUP:
-                       {
-                               identification_t *id = (identification_t*)entry->value;
-                               clone->add(clone, entry->type, id->clone(id));
-                               break;
-                       }
-                       case AUTH_RULE_CA_CERT:
-                       case AUTH_RULE_IM_CERT:
-                       case AUTH_RULE_SUBJECT_CERT:
-                       case AUTH_HELPER_IM_CERT:
-                       case AUTH_HELPER_SUBJECT_CERT:
-                       {
-                               certificate_t *cert = (certificate_t*)entry->value;
-                               clone->add(clone, entry->type, cert->get_ref(cert));
-                               break;
-                       }
-                       case AUTH_HELPER_IM_HASH_URL:
-                       case AUTH_HELPER_SUBJECT_HASH_URL:
-                       {
-                               clone->add(clone, entry->type, strdup(entry->value));
-                               break;
-                       }
-                       case AUTH_RULE_AUTH_CLASS:
-                       case AUTH_RULE_EAP_TYPE:
-                       case AUTH_RULE_EAP_VENDOR:
-                       case AUTH_RULE_CRL_VALIDATION:
-                       case AUTH_RULE_OCSP_VALIDATION:
-                               clone->add(clone, entry->type, (uintptr_t)entry->value);
-                               break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return clone;
-}
-
-/**
- * Implementation of auth_cfg_t.destroy
- */
-static void destroy(private_auth_cfg_t *this)
-{
-       purge(this, FALSE);
-       this->entries->destroy(this->entries);
-       free(this);
-}
-
-/*
- * see header file
- */
-auth_cfg_t *auth_cfg_create()
-{
-       private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
-
-       this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
-       this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
-       this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
-       this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
-       this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
-       this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
-       this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
-       this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
-       this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
-       this->public.destroy = (void(*)(auth_cfg_t*))destroy;
-
-       this->entries = linked_list_create();
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/config/auth_cfg.h b/src/libcharon/config/auth_cfg.h
deleted file mode 100644 (file)
index 7a1454b..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * 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 auth_cfg auth_cfg
- * @{ @ingroup config
- */
-
-#ifndef AUTH_CFG_H_
-#define AUTH_CFG_H_
-
-#include <utils/enumerator.h>
-
-typedef struct auth_cfg_t auth_cfg_t;
-typedef enum auth_rule_t auth_rule_t;
-
-/**
- * Authentication config to use during authentication process.
- *
- * Each authentication config contains a set of rules. These rule-sets are used
- * in two ways:
- * - For configs specifying local authentication behavior, the rules define
- *   which authentication method in which way.
- * - For configs specifying remote peer authentication, the rules define
- *   constraints the peer has to fullfill.
- *
- * Additionally to the rules, there is a set of helper items. These are used
- * to transport credentials during the authentication process.
- */
-enum auth_rule_t {
-
-       /** identity to use for IKEv2 authentication exchange, identification_t* */
-       AUTH_RULE_IDENTITY,
-       /** authentication class, auth_class_t */
-       AUTH_RULE_AUTH_CLASS,
-       /** EAP identity to use within EAP-Identity exchange, identification_t* */
-       AUTH_RULE_EAP_IDENTITY,
-       /** EAP type to propose for peer authentication, eap_type_t */
-       AUTH_RULE_EAP_TYPE,
-       /** EAP vendor for vendor specific type, u_int32_t */
-       AUTH_RULE_EAP_VENDOR,
-       /** certificate authority, certificate_t* */
-       AUTH_RULE_CA_CERT,
-       /** intermediate certificate in trustchain, certificate_t* */
-       AUTH_RULE_IM_CERT,
-       /** subject certificate, certificate_t* */
-       AUTH_RULE_SUBJECT_CERT,
-       /** result of a CRL validation, cert_validation_t */
-       AUTH_RULE_CRL_VALIDATION,
-       /** result of a OCSP validation, cert_validation_t */
-       AUTH_RULE_OCSP_VALIDATION,
-       /** subject is member of a group, identification_t*
-        * The group membership constraint is fulfilled if the subject is member of
-        * one group defined in the constraints. */
-       AUTH_RULE_GROUP,
-
-       /** intermediate certificate, certificate_t* */
-       AUTH_HELPER_IM_CERT,
-       /** subject certificate, certificate_t* */
-       AUTH_HELPER_SUBJECT_CERT,
-       /** Hash and URL of a intermediate certificate, char* */
-       AUTH_HELPER_IM_HASH_URL,
-       /** Hash and URL of a end-entity certificate, char* */
-       AUTH_HELPER_SUBJECT_HASH_URL,
-};
-
-/**
- * enum name for auth_rule_t.
- */
-extern enum_name_t *auth_rule_names;
-
-/**
- * Authentication/Authorization round.
- *
- * RFC4739 defines multiple authentication rounds. This class defines such
- * a round from a configuration perspective, either for the local or the remote
- * peer. Local config are called "rulesets", as they define how we authenticate.
- * Remote peer configs are called "constraits", they define what is needed to
- * complete the authentication round successfully.
- *
- * @verbatim
-
-   [Repeat for each configuration]
-   +--------------------------------------------------+
-   |                                                  |
-   |                                                  |
-   |   +----------+     IKE_AUTH       +--------- +   |
-   |   |  config  |   ----------->     |          |   |
-   |   |  ruleset |                    |          |   |
-   |   +----------+ [ <----------- ]   |          |   |
-   |                [ optional EAP ]   |   Peer   |   |
-   |   +----------+ [ -----------> ]   |          |   |
-   |   |  config  |                    |          |   |
-   |   |  constr. |   <-----------     |          |   |
-   |   +----------+     IKE_AUTH       +--------- +   |
-   |                                                  |
-   |                                                  |
-   +--------------------------------------------------+
-
-   @endverbatim
- *
- * Values for each items are either pointers (casted to void*) or short
- * integers (use uintptr_t cast).
- */
-struct auth_cfg_t {
-
-       /**
-        * Add an rule to the set.
-        *
-        * @param rule          rule type
-        * @param ...           associated value to rule
-        */
-       void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
-
-       /**
-        * Get an rule value.
-        *
-        * @param rule          rule type
-        * @return                      bool if item has been found
-        */
-       void* (*get)(auth_cfg_t *this, auth_rule_t rule);
-
-       /**
-        * Create an enumerator over added rules.
-        *
-        * @return                      enumerator over (auth_rule_t, union{void*,uintpr_t})
-        */
-       enumerator_t* (*create_enumerator)(auth_cfg_t *this);
-
-       /**
-        * Replace an rule at enumerator position.
-        *
-        * @param pos           enumerator position position
-        * @param rule          rule type
-        * @param ...           associated value to rule
-        */
-       void (*replace)(auth_cfg_t *this, enumerator_t *pos,
-                                       auth_rule_t rule, ...);
-
-       /**
-        * Check if a used config fulfills a set of configured constraints.
-        *
-        * @param constraints   required authorization rules
-        * @param log_error             wheter to log compliance errors
-        * @return                              TRUE if this complies with constraints
-        */
-       bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error);
-
-       /**
-        * Merge items from other into this.
-        *
-        * @param other         items to read for merge
-        * @param copy          TRUE to copy items, FALSE to move them
-        */
-       void (*merge)(auth_cfg_t *this, auth_cfg_t *other, bool copy);
-
-       /**
-        * Purge all rules in a config.
-        *
-        * @param keep_ca       wheter to keep AUTH_RULE_CA_CERT entries
-        */
-       void (*purge)(auth_cfg_t *this, bool keep_ca);
-
-       /**
-        * Check two configs for equality.
-        *
-        * @param other         other config to compaire against this
-        * @return                      TRUE if auth infos identical
-        */
-       bool (*equals)(auth_cfg_t *this, auth_cfg_t *other);
-
-       /**
-        * Clone a authentication config, including all rules.
-        *
-        * @return                      cloned configuration
-        */
-       auth_cfg_t* (*clone)(auth_cfg_t *this);
-
-       /**
-        * Destroy a config with all associated rules/values.
-        */
-       void (*destroy)(auth_cfg_t *this);
-};
-
-/**
- * Create a authentication config.
- */
-auth_cfg_t *auth_cfg_create();
-
-#endif /** AUTH_CFG_H_ @}*/
index 6855276..723435c 100644 (file)
@@ -36,7 +36,7 @@ typedef struct peer_cfg_t peer_cfg_t;
 #include <config/child_cfg.h>
 #include <sa/authenticators/authenticator.h>
 #include <sa/authenticators/eap/eap_method.h>
-#include <config/auth_cfg.h>
+#include <credentials/auth_cfg.h>
 
 /**
  * Certificate sending policy. This is also used for certificate
diff --git a/src/libcharon/credentials/credential_manager.c b/src/libcharon/credentials/credential_manager.c
deleted file mode 100644 (file)
index 5714dc0..0000000
+++ /dev/null
@@ -1,1678 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 "credential_manager.h"
-
-#include <daemon.h>
-#include <threading/thread_value.h>
-#include <threading/mutex.h>
-#include <threading/rwlock.h>
-#include <utils/linked_list.h>
-#include <credentials/sets/cert_cache.h>
-#include <credentials/sets/auth_cfg_wrapper.h>
-#include <credentials/sets/ocsp_response_wrapper.h>
-#include <credentials/certificates/x509.h>
-#include <credentials/certificates/crl.h>
-#include <credentials/certificates/ocsp_request.h>
-#include <credentials/certificates/ocsp_response.h>
-
-/**
- * Maximum length of a certificate trust chain
- */
-#define MAX_TRUST_PATH_LEN 7
-
-typedef struct private_credential_manager_t private_credential_manager_t;
-
-/**
- * private data of credential_manager
- */
-struct private_credential_manager_t {
-
-       /**
-        * public functions
-        */
-       credential_manager_t public;
-
-       /**
-        * list of credential sets
-        */
-       linked_list_t *sets;
-
-       /**
-        * thread local set of credentials, linked_list_t with credential_set_t's
-        */
-       thread_value_t *local_sets;
-
-       /**
-        * trust relationship and certificate cache
-        */
-       cert_cache_t *cache;
-
-       /**
-        * certificates queued for persistent caching
-        */
-       linked_list_t *cache_queue;
-
-       /**
-        * read-write lock to sets list
-        */
-       rwlock_t *lock;
-
-       /**
-        * mutex for cache queue
-        */
-       mutex_t *queue_mutex;
-};
-
-/** data to pass to create_private_enumerator */
-typedef struct {
-       private_credential_manager_t *this;
-       key_type_t type;
-       identification_t* keyid;
-} private_data_t;
-
-/** data to pass to create_cert_enumerator */
-typedef struct {
-       private_credential_manager_t *this;
-       certificate_type_t cert;
-       key_type_t key;
-       identification_t *id;
-       bool trusted;
-} cert_data_t;
-
-/** data to pass to create_cdp_enumerator */
-typedef struct {
-       private_credential_manager_t *this;
-       certificate_type_t type;
-       identification_t *id;
-} cdp_data_t;
-
-/** data to pass to create_shared_enumerator */
-typedef struct {
-       private_credential_manager_t *this;
-       shared_key_type_t type;
-       identification_t *me;
-       identification_t *other;
-} shared_data_t;
-
-/** enumerator over local and global sets */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** enumerator over global sets */
-       enumerator_t *global;
-       /** enumerator over local sets */
-       enumerator_t *local;
-} sets_enumerator_t;
-
-/**
- * destroy a sets_enumerator_t
- */
-static void sets_enumerator_destroy(sets_enumerator_t *this)
-{
-       DESTROY_IF(this->global);
-       DESTROY_IF(this->local);
-       free(this);
-}
-
-/**
- * sets_enumerator_t.enumerate
- */
-static bool sets_enumerator_enumerate(sets_enumerator_t *this,
-                                                                         credential_set_t **set)
-{
-       if (this->global)
-       {
-               if (this->global->enumerate(this->global, set))
-               {
-                       return TRUE;
-               }
-               /* end of global sets, look for local */
-               this->global->destroy(this->global);
-               this->global = NULL;
-       }
-       if (this->local)
-       {
-               return this->local->enumerate(this->local, set);
-       }
-       return FALSE;
-}
-
-/**
- * create an enumerator over both, global and local sets
- */
-static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
-{
-       linked_list_t *local;
-       sets_enumerator_t *enumerator = malloc_thing(sets_enumerator_t);
-
-       enumerator->public.enumerate = (void*)sets_enumerator_enumerate;
-       enumerator->public.destroy = (void*)sets_enumerator_destroy;
-       enumerator->global = this->sets->create_enumerator(this->sets);
-       enumerator->local = NULL;
-       local = this->local_sets->get(this->local_sets);
-       if (local)
-       {
-               enumerator->local = local->create_enumerator(local);
-       }
-       return &enumerator->public;
-}
-
-/**
- * cleanup function for cert data
- */
-static void destroy_cert_data(cert_data_t *data)
-{
-       data->this->lock->unlock(data->this->lock);
-       free(data);
-}
-
-/**
- * enumerator constructor for certificates
- */
-static enumerator_t *create_cert(credential_set_t *set, cert_data_t *data)
-{
-       return set->create_cert_enumerator(set, data->cert, data->key,
-                                                                          data->id, data->trusted);
-}
-
-/**
- * Implementation of credential_manager_t.create_cert_enumerator.
- */
-static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
-                                               certificate_type_t certificate, key_type_t key,
-                                               identification_t *id, bool trusted)
-{
-       cert_data_t *data = malloc_thing(cert_data_t);
-       data->this = this;
-       data->cert = certificate;
-       data->key = key;
-       data->id = id;
-       data->trusted = trusted;
-
-       this->lock->read_lock(this->lock);
-       return enumerator_create_nested(create_sets_enumerator(this),
-                                                                       (void*)create_cert, data,
-                                                                       (void*)destroy_cert_data);
-}
-
-/**
- * Implementation of credential_manager_t.get_cert.
- */
-static certificate_t *get_cert(private_credential_manager_t *this,
-                                               certificate_type_t cert, key_type_t key,
-                                               identification_t *id, bool trusted)
-{
-       certificate_t *current, *found = NULL;
-       enumerator_t *enumerator;
-
-       enumerator = create_cert_enumerator(this, cert, key, id, trusted);
-       if (enumerator->enumerate(enumerator, &current))
-       {
-               /* TODO: best match? order by keyid, subject, sualtname */
-               found = current->get_ref(current);
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-
-/**
- * cleanup function for cdp data
- */
-static void destroy_cdp_data(cdp_data_t *data)
-{
-       data->this->lock->unlock(data->this->lock);
-       free(data);
-}
-
-/**
- * enumerator constructor for CDPs
- */
-static enumerator_t *create_cdp(credential_set_t *set, cdp_data_t *data)
-{
-       return set->create_cdp_enumerator(set, data->type, data->id);
-}
-/**
- * Implementation of credential_manager_t.create_cdp_enumerator.
- */
-static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
-                                                               certificate_type_t type, identification_t *id)
-{
-       cdp_data_t *data = malloc_thing(cdp_data_t);
-       data->this = this;
-       data->type = type;
-       data->id = id;
-
-       this->lock->read_lock(this->lock);
-       return enumerator_create_nested(create_sets_enumerator(this),
-                                                                       (void*)create_cdp, data,
-                                                                       (void*)destroy_cdp_data);
-}
-
-/**
- * cleanup function for private data
- */
-static void destroy_private_data(private_data_t *data)
-{
-       data->this->lock->unlock(data->this->lock);
-       free(data);
-}
-
-/**
- * enumerator constructor for private keys
- */
-static enumerator_t *create_private(credential_set_t *set, private_data_t *data)
-{
-       return set->create_private_enumerator(set, data->type, data->keyid);
-}
-
-/**
- * Implementation of credential_manager_t.create_private_enumerator.
- */
-static enumerator_t* create_private_enumerator(
-                                                                       private_credential_manager_t *this,
-                                                                       key_type_t key, identification_t *keyid)
-{
-       private_data_t *data;
-
-       data = malloc_thing(private_data_t);
-       data->this = this;
-       data->type = key;
-       data->keyid = keyid;
-       this->lock->read_lock(this->lock);
-       return enumerator_create_nested(create_sets_enumerator(this),
-                                                                       (void*)create_private, data,
-                                                                       (void*)destroy_private_data);
-}
-
-/**
- * Implementation of credential_manager_t.get_private_by_keyid.
- */
-static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
-                                                                               key_type_t key, identification_t *keyid)
-{
-       private_key_t *found = NULL;
-       enumerator_t *enumerator;
-
-       enumerator = create_private_enumerator(this, key, keyid);
-       if (enumerator->enumerate(enumerator, &found))
-       {
-               found->get_ref(found);
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * cleanup function for shared data
- */
-static void destroy_shared_data(shared_data_t *data)
-{
-       data->this->lock->unlock(data->this->lock);
-       free(data);
-}
-
-/**
- * enumerator constructor for shared keys
- */
-static enumerator_t *create_shared(credential_set_t *set, shared_data_t *data)
-{
-       return set->create_shared_enumerator(set, data->type, data->me, data->other);
-}
-
-/**
- * Implementation of credential_manager_t.create_shared_enumerator.
- */
-static enumerator_t *create_shared_enumerator(private_credential_manager_t *this,
-                                               shared_key_type_t type,
-                                               identification_t *me, identification_t *other)
-{
-       shared_data_t *data = malloc_thing(shared_data_t);
-       data->this = this;
-       data->type = type;
-       data->me = me;
-       data->other = other;
-
-       this->lock->read_lock(this->lock);
-       return enumerator_create_nested(create_sets_enumerator(this),
-                                                                       (void*)create_shared, data,
-                                                                       (void*)destroy_shared_data);
-}
-
-/**
- * Implementation of credential_manager_t.get_shared.
- */
-static shared_key_t *get_shared(private_credential_manager_t *this,
-                                                               shared_key_type_t type, identification_t *me,
-                                                               identification_t *other)
-{
-       shared_key_t *current, *found = NULL;
-       id_match_t *best_me = ID_MATCH_NONE, *best_other = ID_MATCH_NONE;
-       id_match_t *match_me, *match_other;
-       enumerator_t *enumerator;
-
-       enumerator = create_shared_enumerator(this, type, me, other);
-       while (enumerator->enumerate(enumerator, &current, &match_me, &match_other))
-       {
-               if (match_other > best_other ||
-                       (match_other == best_other && match_me > best_me))
-               {
-                       DESTROY_IF(found);
-                       found = current->get_ref(current);
-                       best_me = match_me;
-                       best_other = match_other;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * add a credential set to the thread local list
- */
-static void add_local_set(private_credential_manager_t *this,
-                                                 credential_set_t *set)
-{
-       linked_list_t *sets;
-
-       sets = this->local_sets->get(this->local_sets);
-       if (!sets)
-       {       /* first invocation */
-               sets = linked_list_create();
-               this->local_sets->set(this->local_sets, sets);
-       }
-       sets->insert_last(sets, set);
-}
-
-/**
- * remove a credential set from the thread local list
- */
-static void remove_local_set(private_credential_manager_t *this,
-                                                        credential_set_t *set)
-{
-       linked_list_t *sets;
-
-       sets = this->local_sets->get(this->local_sets);
-       sets->remove(sets, set, NULL);
-}
-
-/**
- * Implementation of credential_manager_t.cache_cert.
- */
-static void cache_cert(private_credential_manager_t *this, certificate_t *cert)
-{
-       credential_set_t *set;
-       enumerator_t *enumerator;
-
-       if (this->lock->try_write_lock(this->lock))
-       {
-               enumerator = this->sets->create_enumerator(this->sets);
-               while (enumerator->enumerate(enumerator, &set))
-               {
-                       set->cache_cert(set, cert);
-               }
-               enumerator->destroy(enumerator);
-               this->lock->unlock(this->lock);
-       }
-       else
-       {       /* we can't cache now as other threads are active, queue for later */
-               this->queue_mutex->lock(this->queue_mutex);
-               this->cache_queue->insert_last(this->cache_queue, cert->get_ref(cert));
-               this->queue_mutex->unlock(this->queue_mutex);
-       }
-}
-
-/**
- * Try to cache certificates queued for caching
- */
-static void cache_queue(private_credential_manager_t *this)
-{
-       credential_set_t *set;
-       certificate_t *cert;
-       enumerator_t *enumerator;
-
-       this->queue_mutex->lock(this->queue_mutex);
-       if (this->cache_queue->get_count(this->cache_queue) > 0 &&
-               this->lock->try_write_lock(this->lock))
-       {
-               while (this->cache_queue->remove_last(this->cache_queue,
-                                                                                         (void**)&cert) == SUCCESS)
-               {
-                       enumerator = this->sets->create_enumerator(this->sets);
-                       while (enumerator->enumerate(enumerator, &set))
-                       {
-                               set->cache_cert(set, cert);
-                       }
-                       enumerator->destroy(enumerator);
-                       cert->destroy(cert);
-               }
-               this->lock->unlock(this->lock);
-       }
-       this->queue_mutex->unlock(this->queue_mutex);
-}
-
-/**
- * forward declaration
- */
-static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
-                                       key_type_t type, identification_t *id, bool online);
-
-/**
- * Do an OCSP request
- */
-static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
-                                                                certificate_t *subject, certificate_t *issuer)
-{
-       certificate_t *request, *response;
-       chunk_t send, receive;
-
-       /* TODO: requestor name, signature */
-       request = lib->creds->create(lib->creds,
-                                               CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
-                                               BUILD_CA_CERT, issuer,
-                                               BUILD_CERT, subject, BUILD_END);
-       if (!request)
-       {
-               DBG1(DBG_CFG, "generating ocsp request failed");
-               return NULL;
-       }
-
-       send = request->get_encoding(request);
-       request->destroy(request);
-
-       DBG1(DBG_CFG, "  requesting ocsp status from '%s' ...", url);
-       if (lib->fetcher->fetch(lib->fetcher, url, &receive,
-                                                       FETCH_REQUEST_DATA, send,
-                                                       FETCH_REQUEST_TYPE, "application/ocsp-request",
-                                                       FETCH_END) != SUCCESS)
-       {
-               DBG1(DBG_CFG, "ocsp request to %s failed", url);
-               chunk_free(&send);
-               return NULL;
-       }
-       chunk_free(&send);
-
-       response = lib->creds->create(lib->creds,
-                                                                 CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
-                                                                 BUILD_BLOB_ASN1_DER, receive, BUILD_END);
-       chunk_free(&receive);
-       if (!response)
-       {
-               DBG1(DBG_CFG, "parsing ocsp response failed");
-               return NULL;
-       }
-       return response;
-}
-
-/**
- * check the signature of an OCSP response
- */
-static bool verify_ocsp(private_credential_manager_t *this,
-                                               ocsp_response_t *response)
-{
-       certificate_t *issuer, *subject;
-       identification_t *responder;
-       ocsp_response_wrapper_t *wrapper;
-       enumerator_t *enumerator;
-       bool verified = FALSE;
-
-       wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
-       add_local_set(this, &wrapper->set);
-
-       subject = &response->certificate;
-       responder = subject->get_issuer(subject);
-       enumerator = create_trusted_enumerator(this, KEY_ANY, responder, FALSE);
-       while (enumerator->enumerate(enumerator, &issuer, NULL))
-       {
-               if (this->cache->issued_by(this->cache, subject, issuer))
-               {
-                       DBG1(DBG_CFG, "  ocsp response correctly signed by \"%Y\"",
-                                                        issuer->get_subject(issuer));
-                       verified = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       remove_local_set(this, &wrapper->set);
-       wrapper->destroy(wrapper);
-       return verified;
-}
-
-/**
- * Get the better of two OCSP responses, and check for usable OCSP info
- */
-static certificate_t *get_better_ocsp(private_credential_manager_t *this,
-                                                                         certificate_t *cand, certificate_t *best,
-                                                                         x509_t *subject, x509_t *issuer,
-                                                                         cert_validation_t *valid, bool cache)
-{
-       ocsp_response_t *response;
-       time_t revocation, this_update, next_update, valid_until;
-       crl_reason_t reason;
-       bool revoked = FALSE;
-
-       response = (ocsp_response_t*)cand;
-
-       /* check ocsp signature */
-       if (!verify_ocsp(this, response))
-       {
-               DBG1(DBG_CFG, "ocsp response verification failed");
-               cand->destroy(cand);
-               return best;
-       }
-       /* check if response contains our certificate */
-       switch (response->get_status(response, subject, issuer, &revocation, &reason,
-                                                                &this_update, &next_update))
-       {
-               case VALIDATION_REVOKED:
-                       /* subject has been revoked by a valid OCSP response */
-                       DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
-                                                 &revocation, TRUE, crl_reason_names, reason);
-                       revoked = TRUE;
-                       break;
-               case VALIDATION_GOOD:
-                       /* results in either good or stale */
-                       break;
-               default:
-               case VALIDATION_FAILED:
-                       /* candidate unusable, does not contain our cert */
-                       DBG1(DBG_CFG, "  ocsp response contains no status on our certificate");
-                       cand->destroy(cand);
-                       return best;
-       }
-
-       /* select the better of the two responses */
-       if (best == NULL || certificate_is_newer(cand, best))
-       {
-               DESTROY_IF(best);
-               best = cand;
-               if (best->get_validity(best, NULL, NULL, &valid_until))
-               {
-                       DBG1(DBG_CFG, "  ocsp response is valid: until %T",
-                                                        &valid_until, FALSE);
-                       *valid = VALIDATION_GOOD;
-                       if (cache)
-                       {       /* cache non-stale only, stale certs get refetched */
-                               cache_cert(this, best);
-                       }
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "  ocsp response is stale: since %T",
-                                                        &valid_until, FALSE);
-                       *valid = VALIDATION_STALE;
-               }
-       }
-       else
-       {
-               *valid = VALIDATION_STALE;
-               cand->destroy(cand);
-       }
-       if (revoked)
-       {       /* revoked always counts, even if stale */
-               *valid = VALIDATION_REVOKED;
-       }
-       return best;
-}
-
-/**
- * validate a x509 certificate using OCSP
- */
-static cert_validation_t check_ocsp(private_credential_manager_t *this,
-                                                                       x509_t *subject, x509_t *issuer,
-                                                                       auth_cfg_t *auth)
-{
-       enumerator_t *enumerator;
-       cert_validation_t valid = VALIDATION_SKIPPED;
-       certificate_t *best = NULL, *current;
-       identification_t *keyid = NULL;
-       public_key_t *public;
-       chunk_t chunk;
-       char *uri = NULL;
-
-       /** lookup cache for valid OCSP responses */
-       enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
-                                                                               KEY_ANY, NULL, FALSE);
-       while (enumerator->enumerate(enumerator, &current))
-       {
-               current->get_ref(current);
-               best = get_better_ocsp(this, current, best, subject, issuer,
-                                                          &valid, FALSE);
-               if (best && valid != VALIDATION_STALE)
-               {
-                       DBG1(DBG_CFG, "  using cached ocsp response");
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* derive the authorityKeyIdentifier from the issuer's public key */
-       current = &issuer->interface;
-       public = current->get_public_key(current);
-       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
-       {
-               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
-       }
-       /** fetch from configured OCSP responder URLs */
-       if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
-       {
-               enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
-               while (enumerator->enumerate(enumerator, &uri))
-               {
-                       current = fetch_ocsp(this, uri, &subject->interface,
-                                                                &issuer->interface);
-                       if (current)
-                       {
-                               best = get_better_ocsp(this, current, best, subject, issuer,
-                                                                          &valid, TRUE);
-                               if (best && valid != VALIDATION_STALE)
-                               {
-                                       break;
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       DESTROY_IF(public);
-       DESTROY_IF(keyid);
-
-       /* fallback to URL fetching from subject certificate's URIs */
-       if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
-       {
-               enumerator = subject->create_ocsp_uri_enumerator(subject);
-               while (enumerator->enumerate(enumerator, &uri))
-               {
-                       current = fetch_ocsp(this, uri, &subject->interface,
-                                                                &issuer->interface);
-                       if (current)
-                       {
-                               best = get_better_ocsp(this, current, best, subject, issuer,
-                                                                          &valid, TRUE);
-                               if (best && valid != VALIDATION_STALE)
-                               {
-                                       break;
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       /* an uri was found, but no result. switch validation state to failed */
-       if (valid == VALIDATION_SKIPPED && uri)
-       {
-               valid = VALIDATION_FAILED;
-       }
-       if (auth)
-       {
-               auth->add(auth, AUTH_RULE_OCSP_VALIDATION, valid);
-               if (valid == VALIDATION_GOOD)
-               {       /* successful OCSP check fulfills also CRL constraint */
-                       auth->add(auth, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
-               }
-       }
-       DESTROY_IF(best);
-       return valid;
-}
-
-/**
- * fetch a CRL from an URL
- */
-static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
-{
-       certificate_t *crl;
-       chunk_t chunk;
-
-       DBG1(DBG_CFG, "  fetching crl from '%s' ...", url);
-       if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
-       {
-               DBG1(DBG_CFG, "crl fetching failed");
-               return NULL;
-       }
-       crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
-                                                        BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
-       chunk_free(&chunk);
-       if (!crl)
-       {
-               DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
-               return NULL;
-       }
-       return crl;
-}
-
-/**
- * check the signature of an CRL
- */
-static bool verify_crl(private_credential_manager_t *this, certificate_t *crl)
-{
-       certificate_t *issuer;
-       enumerator_t *enumerator;
-       bool verified = FALSE;
-
-       enumerator = create_trusted_enumerator(this, KEY_ANY, crl->get_issuer(crl),
-                                                                                  FALSE);
-       while (enumerator->enumerate(enumerator, &issuer, NULL))
-       {
-               if (this->cache->issued_by(this->cache, crl, issuer))
-               {
-                       DBG1(DBG_CFG, "  crl correctly signed by \"%Y\"",
-                                                  issuer->get_subject(issuer));
-                       verified = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       return verified;
-}
-
-/**
- * Get the better of two CRLs, and check for usable CRL info
- */
-static certificate_t *get_better_crl(private_credential_manager_t *this,
-                                                                        certificate_t *cand, certificate_t *best,
-                                                                        x509_t *subject, x509_t *issuer,
-                                                                        cert_validation_t *valid, bool cache)
-{
-       enumerator_t *enumerator;
-       time_t revocation, valid_until;
-       crl_reason_t reason;
-       chunk_t serial;
-       crl_t *crl;
-
-       /* check CRL signature */
-       if (!verify_crl(this, cand))
-       {
-               DBG1(DBG_CFG, "crl response verification failed");
-               cand->destroy(cand);
-               return best;
-       }
-
-       crl = (crl_t*)cand;
-       enumerator = crl->create_enumerator(crl);
-       while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
-       {
-               if (chunk_equals(serial, subject->get_serial(subject)))
-               {
-                       DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
-                                &revocation, TRUE, crl_reason_names, reason);
-                       *valid = VALIDATION_REVOKED;
-                       enumerator->destroy(enumerator);
-                       DESTROY_IF(best);
-                       return cand;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* select the better of the two CRLs */
-       if (best == NULL || crl_is_newer(crl, (crl_t*)best))
-       {
-               DESTROY_IF(best);
-               best = cand;
-               if (best->get_validity(best, NULL, NULL, &valid_until))
-               {
-                       DBG1(DBG_CFG, "  crl is valid: until %T", &valid_until, FALSE);
-                       *valid = VALIDATION_GOOD;
-                       if (cache)
-                       {       /* we cache non-stale crls only, as a stale crls are refetched */
-                               cache_cert(this, best);
-                       }
-               }
-               else
-               {
-                       DBG1(DBG_CFG, "  crl is stale: since %T", &valid_until, FALSE);
-                       *valid = VALIDATION_STALE;
-               }
-       }
-       else
-       {
-               *valid = VALIDATION_STALE;
-               cand->destroy(cand);
-       }
-       return best;
-}
-
-/**
- * validate a x509 certificate using CRL
- */
-static cert_validation_t check_crl(private_credential_manager_t *this,
-                                                                  x509_t *subject, x509_t *issuer,
-                                                                  auth_cfg_t *auth)
-{
-       cert_validation_t valid = VALIDATION_SKIPPED;
-       identification_t *keyid = NULL;
-       certificate_t *best = NULL;
-       certificate_t *current;
-       public_key_t *public;
-       enumerator_t *enumerator;
-       chunk_t chunk;
-       char *uri = NULL;
-
-       /* derive the authorityKeyIdentifier from the issuer's public key */
-       current = &issuer->interface;
-       public = current->get_public_key(current);
-       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
-       {
-               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
-
-               /* find a cached crl by authorityKeyIdentifier */
-               enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY,
-                                                                                       keyid, FALSE);
-               while (enumerator->enumerate(enumerator, &current))
-               {
-                       current->get_ref(current);
-                       best = get_better_crl(this, current, best, subject, issuer,
-                                                                 &valid, FALSE);
-                       if (best && valid != VALIDATION_STALE)
-                       {
-                               DBG1(DBG_CFG, "  using cached crl");
-                               break;
-                       }
-               }
-               enumerator->destroy(enumerator);
-
-               /* fallback to fetching crls from credential sets cdps */
-               if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
-               {
-                       enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
-
-                       while (enumerator->enumerate(enumerator, &uri))
-                       {
-                               current = fetch_crl(this, uri);
-                               if (current)
-                               {
-                                       best = get_better_crl(this, current, best, subject, issuer,
-                                                                                 &valid, TRUE);
-                                       if (best && valid != VALIDATION_STALE)
-                                       {
-                                               break;
-                                       }
-                               }
-                       }
-                       enumerator->destroy(enumerator);
-               }
-               keyid->destroy(keyid);
-       }
-       DESTROY_IF(public);
-
-       /* fallback to fetching crls from cdps from subject's certificate */
-       if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
-       {
-               enumerator = subject->create_crl_uri_enumerator(subject);
-
-               while (enumerator->enumerate(enumerator, &uri))
-               {
-                       current = fetch_crl(this, uri);
-                       if (current)
-                       {
-                               best = get_better_crl(this, current, best, subject, issuer,
-                                                                         &valid, TRUE);
-                               if (best && valid != VALIDATION_STALE)
-                               {
-                                       break;
-                               }
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-
-       /* an uri was found, but no result. switch validation state to failed */
-       if (valid == VALIDATION_SKIPPED && uri)
-       {
-               valid = VALIDATION_FAILED;
-       }
-       if (auth)
-       {
-               if (valid == VALIDATION_SKIPPED)
-               {       /* if we skipped CRL validation, we use the result of OCSP for
-                        * constraint checking */
-                       auth->add(auth, AUTH_RULE_CRL_VALIDATION,
-                                         auth->get(auth, AUTH_RULE_OCSP_VALIDATION));
-               }
-               else
-               {
-                       auth->add(auth, AUTH_RULE_CRL_VALIDATION, valid);
-               }
-       }
-       DESTROY_IF(best);
-       return valid;
-}
-
-/**
- * check a certificate for optional IP address block constraints
- */
-static bool check_ip_addr_block_constraints(x509_t *subject, x509_t *issuer)
-{
-       bool subject_constraint = subject->get_flags(subject) & X509_IP_ADDR_BLOCKS;
-       bool issuer_constraint = issuer->get_flags(issuer) & X509_IP_ADDR_BLOCKS;
-       bool contained = TRUE;
-
-       enumerator_t *subject_enumerator, *issuer_enumerator;
-       traffic_selector_t *subject_ts, *issuer_ts;
-
-       if (!subject_constraint && !issuer_constraint)
-       {
-               return TRUE;
-       }
-       if (!subject_constraint)
-       {
-               DBG1(DBG_CFG, "subject certficate lacks ipAddrBlocks extension");
-               return FALSE;
-       }
-       if (!issuer_constraint)
-       {
-               DBG1(DBG_CFG, "issuer certficate lacks ipAddrBlocks extension");
-               return FALSE;
-       }
-       subject_enumerator = subject->create_ipAddrBlock_enumerator(subject);
-       while (subject_enumerator->enumerate(subject_enumerator, &subject_ts))
-       {
-               contained = FALSE;
-
-               issuer_enumerator = issuer->create_ipAddrBlock_enumerator(issuer);
-               while (issuer_enumerator->enumerate(issuer_enumerator, &issuer_ts))
-               {
-                       if (subject_ts->is_contained_in(subject_ts, issuer_ts))
-                       {
-                               DBG2(DBG_CFG, "  subject address block %R is contained in "
-                                                         "issuer address block %R", subject_ts, issuer_ts);
-                               contained = TRUE;
-                               break;
-                       }
-               }
-               issuer_enumerator->destroy(issuer_enumerator);
-               if (!contained)
-               {
-                       DBG1(DBG_CFG, "subject address block %R is not contained in any "
-                                                 "issuer address block", subject_ts);
-                       break;
-               }
-       }
-       subject_enumerator->destroy(subject_enumerator);
-       return contained;
-}
-
-/**
- * check a certificate for its lifetime
- */
-static bool check_certificate(private_credential_manager_t *this,
-                                                         certificate_t *subject, certificate_t *issuer,
-                                                         bool online, int pathlen, auth_cfg_t *auth)
-{
-       time_t not_before, not_after;
-
-       if (!subject->get_validity(subject, NULL, &not_before, &not_after))
-       {
-               DBG1(DBG_CFG, "subject certificate invalid (valid from %T to %T)",
-                        &not_before, FALSE, &not_after, FALSE);
-               return FALSE;
-       }
-       if (!issuer->get_validity(issuer, NULL, &not_before, &not_after))
-       {
-               DBG1(DBG_CFG, "issuer certificate invalid (valid from %T to %T)",
-                        &not_before, FALSE, &not_after, FALSE);
-               return FALSE;
-       }
-       if (issuer->get_type(issuer) == CERT_X509 &&
-               subject->get_type(subject) == CERT_X509)
-       {
-               int pathlen_constraint;
-               x509_t *x509;
-
-               if (!check_ip_addr_block_constraints((x509_t*)subject, (x509_t*)issuer))
-               {
-                       return FALSE;
-               }
-
-               /* check path length constraint */
-               x509 = (x509_t*)issuer;
-               pathlen_constraint = x509->get_pathLenConstraint(x509);
-               if (pathlen_constraint != X509_NO_PATH_LEN_CONSTRAINT &&
-                       pathlen > pathlen_constraint)
-               {
-                       DBG1(DBG_CFG, "path length of %d violates constraint of %d",
-                                pathlen, pathlen_constraint);
-                       return FALSE;
-               }
-
-               if (online)
-               {
-                       DBG1(DBG_CFG, "checking certificate status of \"%Y\"",
-                                                  subject->get_subject(subject));
-                       switch (check_ocsp(this, (x509_t*)subject, (x509_t*)issuer, auth))
-                       {
-                               case VALIDATION_GOOD:
-                                       DBG1(DBG_CFG, "certificate status is good");
-                                       return TRUE;
-                               case VALIDATION_REVOKED:
-                                       /* has already been logged */
-                                       return FALSE;
-                               case VALIDATION_SKIPPED:
-                                       DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
-                                       break;
-                               case VALIDATION_STALE:
-                                       DBG1(DBG_CFG, "ocsp information stale, fallback to crl");
-                                       break;
-                               case VALIDATION_FAILED:
-                                       DBG1(DBG_CFG, "ocsp check failed, fallback to crl");
-                                       break;
-                       }
-                       switch (check_crl(this, (x509_t*)subject, (x509_t*)issuer, auth))
-                       {
-                               case VALIDATION_GOOD:
-                                       DBG1(DBG_CFG, "certificate status is good");
-                                       return TRUE;
-                               case VALIDATION_REVOKED:
-                                       /* has already been logged */
-                                       return FALSE;
-                               case VALIDATION_FAILED:
-                               case VALIDATION_SKIPPED:
-                                       DBG1(DBG_CFG, "certificate status is not available");
-                                       break;
-                               case VALIDATION_STALE:
-                                       DBG1(DBG_CFG, "certificate status is unknown, crl is stale");
-                                       break;
-                       }
-               }
-       }
-       return TRUE;
-}
-
-/**
- * Get a trusted certificate from a credential set
- */
-static certificate_t *get_pretrusted_cert(private_credential_manager_t *this,
-                                                                                 key_type_t type, identification_t *id)
-{
-       certificate_t *subject;
-       public_key_t *public;
-
-       subject = get_cert(this, CERT_ANY, type, id, TRUE);
-       if (!subject)
-       {
-               return NULL;
-       }
-       public = subject->get_public_key(subject);
-       if (!public)
-       {
-               subject->destroy(subject);
-               return NULL;
-       }
-       public->destroy(public);
-       return subject;
-}
-
-/**
- * Get the issuing certificate of a subject certificate
- */
-static certificate_t *get_issuer_cert(private_credential_manager_t *this,
-                                                                         certificate_t *subject, bool trusted)
-{
-       enumerator_t *enumerator;
-       certificate_t *issuer = NULL, *candidate;
-
-       enumerator = create_cert_enumerator(this, subject->get_type(subject), KEY_ANY,
-                                                                               subject->get_issuer(subject), trusted);
-       while (enumerator->enumerate(enumerator, &candidate))
-       {
-               if (this->cache->issued_by(this->cache, subject, candidate))
-               {
-                       issuer = candidate->get_ref(candidate);
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return issuer;
-}
-
-/**
- * try to verify the trust chain of subject, return TRUE if trusted
- */
-static bool verify_trust_chain(private_credential_manager_t *this,
-                                                          certificate_t *subject, auth_cfg_t *result,
-                                                          bool trusted, bool online)
-{
-       certificate_t *current, *issuer;
-       auth_cfg_t *auth;
-       int pathlen;
-
-       auth = auth_cfg_create();
-       current = subject->get_ref(subject);
-
-       for (pathlen = 0; pathlen <= MAX_TRUST_PATH_LEN; pathlen++)
-       {
-               issuer = get_issuer_cert(this, current, TRUE);
-               if (issuer)
-               {
-                       /* accept only self-signed CAs as trust anchor */
-                       if (this->cache->issued_by(this->cache, issuer, issuer))
-                       {
-                               auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
-                               DBG1(DBG_CFG, "  using trusted ca certificate \"%Y\"",
-                                                         issuer->get_subject(issuer));
-                               trusted = TRUE;
-                       }
-                       else
-                       {
-                               auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
-                               DBG1(DBG_CFG, "  using trusted intermediate ca certificate "
-                                        "\"%Y\"", issuer->get_subject(issuer));
-                       }
-               }
-               else
-               {
-                       issuer = get_issuer_cert(this, current, FALSE);
-                       if (issuer)
-                       {
-                               if (current->equals(current, issuer))
-                               {
-                                       DBG1(DBG_CFG, "  self-signed certificate \"%Y\" is not trusted",
-                                                current->get_subject(current));
-                                       issuer->destroy(issuer);
-                                       break;
-                               }
-                               auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
-                               DBG1(DBG_CFG, "  using untrusted intermediate certificate "
-                                        "\"%Y\"", issuer->get_subject(issuer));
-                       }
-                       else
-                       {
-                               DBG1(DBG_CFG, "no issuer certificate found for \"%Y\"",
-                                        current->get_subject(current));
-                               break;
-                       }
-               }
-               if (!check_certificate(this, current, issuer, online, pathlen,
-                                                          current == subject ? auth : NULL))
-               {
-                       trusted = FALSE;
-                       issuer->destroy(issuer);
-                       break;
-               }
-               current->destroy(current);
-               current = issuer;
-               if (trusted)
-               {
-                       DBG1(DBG_CFG, "  reached self-signed root ca with a path length of %d",
-                                                 pathlen);
-                       break;
-               }
-       }
-       current->destroy(current);
-       if (pathlen > MAX_TRUST_PATH_LEN)
-       {
-               DBG1(DBG_CFG, "maximum path length of %d exceeded", MAX_TRUST_PATH_LEN);
-       }
-       if (trusted)
-       {
-               result->merge(result, auth, FALSE);
-       }
-       auth->destroy(auth);
-       return trusted;
-}
-
-/**
- * enumerator for trusted certificates
- */
-typedef struct {
-       /** implements enumerator_t interface */
-       enumerator_t public;
-       /** enumerator over candidate peer certificates */
-       enumerator_t *candidates;
-       /** reference to the credential_manager */
-       private_credential_manager_t *this;
-       /** type of the requested key */
-       key_type_t type;
-       /** identity the requested key belongs to */
-       identification_t *id;
-       /** TRUE to do CRL/OCSP checking */
-       bool online;
-       /** pretrusted certificate we have served at first invocation */
-       certificate_t *pretrusted;
-       /** currently enumerating auth config */
-       auth_cfg_t *auth;
-} trusted_enumerator_t;
-
-/**
- * Implements trusted_enumerator_t.enumerate
- */
-static bool trusted_enumerate(trusted_enumerator_t *this,
-                                                         certificate_t **cert, auth_cfg_t **auth)
-{
-       certificate_t *current;
-
-       DESTROY_IF(this->auth);
-       this->auth = auth_cfg_create();
-
-       if (!this->candidates)
-       {
-               /* first invocation, build enumerator for next one */
-               this->candidates = create_cert_enumerator(this->this, CERT_ANY,
-                                                                                                 this->type, this->id, FALSE);
-               /* check if we have a trusted certificate for that peer */
-               this->pretrusted = get_pretrusted_cert(this->this, this->type, this->id);
-               if (this->pretrusted)
-               {
-                       /* if we find a trusted self signed certificate, we just accept it.
-                        * However, in order to fulfill authorization rules, we try to build
-                        * the trust chain if it is not self signed */
-                       if (this->this->cache->issued_by(this->this->cache,
-                                                                  this->pretrusted, this->pretrusted) ||
-                               verify_trust_chain(this->this, this->pretrusted, this->auth,
-                                                                  TRUE, this->online))
-                       {
-                               this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT,
-                                                               this->pretrusted->get_ref(this->pretrusted));
-                               DBG1(DBG_CFG, "  using trusted certificate \"%Y\"",
-                                        this->pretrusted->get_subject(this->pretrusted));
-                               *cert = this->pretrusted;
-                               if (auth)
-                               {
-                                       *auth = this->auth;
-                               }
-                               return TRUE;
-                       }
-               }
-       }
-       /* try to verify the trust chain for each certificate found */
-       while (this->candidates->enumerate(this->candidates, &current))
-       {
-               if (this->pretrusted &&
-                       this->pretrusted->equals(this->pretrusted, current))
-               {       /* skip pretrusted certificate we already served */
-                       continue;
-               }
-
-               DBG1(DBG_CFG, "  using certificate \"%Y\"",
-                        current->get_subject(current));
-               if (verify_trust_chain(this->this, current, this->auth, FALSE,
-                                                          this->online))
-               {
-                       *cert = current;
-                       if (auth)
-                       {
-                               *auth = this->auth;
-                       }
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-/**
- * Implements trusted_enumerator_t.destroy
- */
-static void trusted_destroy(trusted_enumerator_t *this)
-{
-       DESTROY_IF(this->pretrusted);
-       DESTROY_IF(this->auth);
-       DESTROY_IF(this->candidates);
-       free(this);
-}
-
-/**
- * create an enumerator over trusted certificates and their trustchain
- */
-static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
-                                       key_type_t type, identification_t *id, bool online)
-{
-       trusted_enumerator_t *enumerator = malloc_thing(trusted_enumerator_t);
-
-       enumerator->public.enumerate = (void*)trusted_enumerate;
-       enumerator->public.destroy = (void*)trusted_destroy;
-
-       enumerator->candidates = NULL;
-       enumerator->this = this;
-       enumerator->type = type;
-       enumerator->id = id;
-       enumerator->online = online;
-       enumerator->pretrusted = NULL;
-       enumerator->auth = NULL;
-
-       return &enumerator->public;
-}
-
-/**
- * enumerator for public keys
- */
-typedef struct {
-       /** implements enumerator_t interface */
-       enumerator_t public;
-       /** enumerator over candidate peer certificates */
-       enumerator_t *inner;
-       /** reference to the credential_manager */
-       private_credential_manager_t *this;
-       /** currently enumerating key */
-       public_key_t *current;
-       /** credset wrapper around auth config */
-       auth_cfg_wrapper_t *wrapper;
-} public_enumerator_t;
-
-/**
- * Implements public_enumerator_t.enumerate
- */
-static bool public_enumerate(public_enumerator_t *this,
-                                                        public_key_t **key, auth_cfg_t **auth)
-{
-       certificate_t *cert;
-
-       while (this->inner->enumerate(this->inner, &cert, auth))
-       {
-               DESTROY_IF(this->current);
-               this->current = cert->get_public_key(cert);
-               if (this->current)
-               {
-                       *key = this->current;
-                       return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-/**
- * Implements public_enumerator_t.destroy
- */
-static void public_destroy(public_enumerator_t *this)
-{
-       DESTROY_IF(this->current);
-       this->inner->destroy(this->inner);
-       if (this->wrapper)
-       {
-               remove_local_set(this->this, &this->wrapper->set);
-               this->wrapper->destroy(this->wrapper);
-       }
-       this->this->lock->unlock(this->this->lock);
-
-       /* check for delayed certificate cache queue */
-       cache_queue(this->this);
-       free(this);
-}
-
-/**
- * Implementation of credential_manager_t.create_public_enumerator.
- */
-static enumerator_t* create_public_enumerator(private_credential_manager_t *this,
-                                               key_type_t type, identification_t *id, auth_cfg_t *auth)
-{
-       public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
-
-       enumerator->public.enumerate = (void*)public_enumerate;
-       enumerator->public.destroy = (void*)public_destroy;
-       enumerator->inner = create_trusted_enumerator(this, type, id, TRUE);
-       enumerator->this = this;
-       enumerator->current = NULL;
-       enumerator->wrapper = NULL;
-       if (auth)
-       {
-               enumerator->wrapper = auth_cfg_wrapper_create(auth);
-               add_local_set(this, &enumerator->wrapper->set);
-       }
-       this->lock->read_lock(this->lock);
-       return &enumerator->public;
-}
-
-/**
- * Check if a certificate's keyid is contained in the auth helper
- */
-static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
-{
-       enumerator_t *enumerator;
-       identification_t *value;
-       auth_rule_t type;
-       bool found = FALSE;
-
-       enumerator = auth->create_enumerator(auth);
-       while (enumerator->enumerate(enumerator, &type, &value))
-       {
-               if (type == AUTH_RULE_CA_CERT &&
-                       cert->equals(cert, (certificate_t*)value))
-               {
-                       found = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * build a trustchain from subject up to a trust anchor in trusted
- */
-static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
-                                                                        certificate_t *subject, auth_cfg_t *auth)
-{
-       certificate_t *issuer, *current;
-       auth_cfg_t *trustchain;
-       int pathlen = 0;
-
-       trustchain = auth_cfg_create();
-
-       current = auth->get(auth, AUTH_RULE_CA_CERT);
-       if (!current)
-       {
-               /* no trust anchor specified, return this cert only */
-               trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT,
-                                               subject->get_ref(subject));
-               return trustchain;
-       }
-       current = subject->get_ref(subject);
-       while (TRUE)
-       {
-               if (auth_contains_cacert(auth, current))
-               {
-                       trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
-                       return trustchain;
-               }
-               if (subject == current)
-               {
-                       trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT, current);
-               }
-               else
-               {
-                       trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
-               }
-               issuer = get_issuer_cert(this, current, FALSE);
-               if (!issuer || issuer->equals(issuer, current) ||
-                       pathlen > MAX_TRUST_PATH_LEN)
-               {
-                       DESTROY_IF(issuer);
-                       break;
-               }
-               current = issuer;
-               pathlen++;
-       }
-       trustchain->destroy(trustchain);
-       return NULL;
-}
-
-/**
- * find a private key of a give certificate
- */
-static private_key_t *get_private_by_cert(private_credential_manager_t *this,
-                                                                                 certificate_t *cert, key_type_t type)
-{
-       private_key_t *private = NULL;
-       identification_t *keyid;
-       chunk_t chunk;
-       public_key_t *public;
-
-       public = cert->get_public_key(cert);
-       if (public)
-       {
-               if (public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
-               {
-                       keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
-                       private = get_private_by_keyid(this, type, keyid);
-                       keyid->destroy(keyid);
-               }
-               public->destroy(public);
-       }
-       return private;
-}
-
-/**
- * Implementation of credential_manager_t.get_private.
- */
-static private_key_t *get_private(private_credential_manager_t *this,
-                                                                 key_type_t type, identification_t *id,
-                                                                 auth_cfg_t *auth)
-{
-       enumerator_t *enumerator;
-       certificate_t *cert;
-       private_key_t *private = NULL;
-       auth_cfg_t *trustchain;
-
-       /* check if this is a lookup by key ID, and do it if so */
-       if (id && id->get_type(id) == ID_KEY_ID)
-       {
-               private = get_private_by_keyid(this, type, id);
-               if (private)
-               {
-                       return private;
-               }
-       }
-
-       /* if a specific certificate is preferred, check for a matching key */
-       cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
-       if (cert)
-       {
-               private = get_private_by_cert(this, cert, type);
-               if (private)
-               {
-                       trustchain = build_trustchain(this, cert, auth);
-                       if (trustchain)
-                       {
-                               auth->merge(auth, trustchain, FALSE);
-                               trustchain->destroy(trustchain);
-                       }
-                       return private;
-               }
-       }
-
-       /* try to build a trust chain for each certificate found */
-       enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
-       while (enumerator->enumerate(enumerator, &cert))
-       {
-               private = get_private_by_cert(this, cert, type);
-               if (private)
-               {
-                       trustchain = build_trustchain(this, cert, auth);
-                       if (trustchain)
-                       {
-                               auth->merge(auth, trustchain, FALSE);
-                               trustchain->destroy(trustchain);
-                               break;
-                       }
-                       private->destroy(private);
-                       private = NULL;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* if no valid trustchain was found, fall back to the first usable cert */
-       if (!private)
-       {
-               enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
-               while (enumerator->enumerate(enumerator, &cert))
-               {
-                       private = get_private_by_cert(this, cert, type);
-                       if (private)
-                       {
-                               auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert));
-                               break;
-                       }
-               }
-               enumerator->destroy(enumerator);
-       }
-       return private;
-}
-
-/**
- * Implementation of credential_manager_t.flush_cache.
- */
-static void flush_cache(private_credential_manager_t *this,
-                                               certificate_type_t type)
-{
-       this->cache->flush(this->cache, type);
-}
-
-/**
- * Implementation of credential_manager_t.add_set.
- */
-static void add_set(private_credential_manager_t *this,
-                                                          credential_set_t *set)
-{
-       this->lock->write_lock(this->lock);
-       this->sets->insert_last(this->sets, set);
-       this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of credential_manager_t.remove_set.
- */
-static void remove_set(private_credential_manager_t *this, credential_set_t *set)
-{
-       this->lock->write_lock(this->lock);
-       this->sets->remove(this->sets, set, NULL);
-       this->lock->unlock(this->lock);
-}
-
-/**
- * Implementation of credential_manager_t.destroy
- */
-static void destroy(private_credential_manager_t *this)
-{
-       cache_queue(this);
-       this->cache_queue->destroy(this->cache_queue);
-       this->sets->remove(this->sets, this->cache, NULL);
-       this->sets->destroy(this->sets);
-       this->local_sets->destroy(this->local_sets);
-       this->cache->destroy(this->cache);
-       this->lock->destroy(this->lock);
-       this->queue_mutex->destroy(this->queue_mutex);
-       free(this);
-}
-
-/*
- * see header file
- */
-credential_manager_t *credential_manager_create()
-{
-       private_credential_manager_t *this = malloc_thing(private_credential_manager_t);
-
-       this->public.create_cert_enumerator = (enumerator_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *id,bool))create_cert_enumerator;
-       this->public.create_shared_enumerator = (enumerator_t *(*)(credential_manager_t *this, shared_key_type_t type,identification_t *me, identification_t *other))create_shared_enumerator;
-       this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, certificate_type_t type, identification_t *id))create_cdp_enumerator;
-       this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
-       this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
-       this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_cfg_t*))get_private;
-       this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_cfg_t *aut))create_public_enumerator;
-       this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
-       this->public.cache_cert = (void(*)(credential_manager_t*, certificate_t *cert))cache_cert;
-       this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
-       this->public.remove_set = (void(*)(credential_manager_t*, credential_set_t *set))remove_set;
-       this->public.destroy = (void(*)(credential_manager_t*))destroy;
-
-       this->sets = linked_list_create();
-       this->local_sets = thread_value_create((thread_cleanup_t)this->sets->destroy);
-       this->cache = cert_cache_create();
-       this->cache_queue = linked_list_create();
-       this->sets->insert_first(this->sets, this->cache);
-       this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-       this->queue_mutex = mutex_create(MUTEX_TYPE_DEFAULT);
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/credentials/credential_manager.h b/src/libcharon/credentials/credential_manager.h
deleted file mode 100644 (file)
index 0448da9..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 credential_manager credential_manager
- * @{ @ingroup ccredentials
- */
-
-#ifndef CREDENTIAL_MANAGER_H_
-#define CREDENTIAL_MANAGER_H_
-
-#include <utils/identification.h>
-#include <utils/enumerator.h>
-#include <config/auth_cfg.h>
-#include <credentials/credential_set.h>
-#include <credentials/keys/private_key.h>
-#include <credentials/keys/shared_key.h>
-#include <credentials/certificates/certificate.h>
-
-typedef struct credential_manager_t credential_manager_t;
-
-/**
- * Manages credentials using credential_sets.
- *
- * The credential manager is the entry point of the credential framework. It
- * uses so called "sets" to access credentials in a modular fashion, these
- * are implemented through the credential_set_t interface.
- * The manager additionally does trust chain verification and trust status
- * chaching. A set may call the managers methods if it needs credentials itself,
- * the manager uses recursive locking.
- *
- * @verbatim
-
-  +-------+        +----------------+
-  |   A   |        |                |          +------------------+
-  |   u   | -----> |                | ------>  |  +------------------+
-  |   t   |        |   credential-  |          |  |  +------------------+
-  |   h   | -----> |     manager    | ------>  +--|  |   credential-    | => IPC
-  |   e   |        |                |             +--|       sets       |
-  |   n   |   +--> |                | ------>        +------------------+
-  |   t   |   |    |                |                        |
-  |   i   |   |    |                |                        |
-  |   c   |   |    +----------------+                        |
-  |   a   |   |                                              |
-  |   t   |   +----------------------------------------------+
-  |   o   |                    may be recursive
-  |   r   |
-  +-------+
-
-   @endverbatim
- *
- * The credential manager uses rwlocks for performance reasons, credential
- * sets must be fully thread save.
- */
-struct credential_manager_t {
-
-       /**
-        * Create an enumerator over all certificates.
-        *
-        * @param cert          kind of certificate
-        * @param key           kind of key in certificate
-        * @param id            subject this certificate belongs to
-        * @param trusted       TRUE to list trusted certificates only
-        * @return                      enumerator over the certificates
-        */
-       enumerator_t *(*create_cert_enumerator)(credential_manager_t *this,
-                                                               certificate_type_t cert, key_type_t key,
-                                                               identification_t *id, bool trusted);
-       /**
-        * Create an enumerator over all shared keys.
-        *
-        * The enumerator enumerates over:
-        *  shared_key_t*, id_match_t me, id_match_t other
-        * But must accepts values for the id_matches.
-        *
-        * @param type          kind of requested shared key
-        * @param first         first subject between key is shared
-        * @param second        second subject between key is shared
-        * @return                      enumerator over shared keys
-        */
-       enumerator_t *(*create_shared_enumerator)(credential_manager_t *this,
-                                                               shared_key_type_t type,
-                                                               identification_t *first, identification_t *second);
-       /**
-        * Create an enumerator over all Certificate Distribution Points.
-        *
-        * @param type          kind of certificate the point distributes
-        * @param id            identification of the distributed certificate
-        * @return                      enumerator of CDPs as char*
-        */
-       enumerator_t *(*create_cdp_enumerator)(credential_manager_t *this,
-                                                               certificate_type_t type, identification_t *id);
-       /**
-        * Get a trusted or untrusted certificate.
-        *
-        * @param cert          kind of certificate
-        * @param key           kind of key in certificate
-        * @param id            subject this certificate belongs to
-        * @param trusted       TRUE to get a trusted certificate only
-        * @return                      certificate, if found, NULL otherwise
-        */
-       certificate_t *(*get_cert)(credential_manager_t *this,
-                                                          certificate_type_t cert, key_type_t key,
-                                                          identification_t *id, bool trusted);
-       /**
-        * Get the best matching shared key for two IDs.
-        *
-        * @param type          kind of requested shared key
-        * @param me            own identity
-        * @param other         peers identity
-        * @return                      shared_key_t, NULL if none found
-        */
-       shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
-                                                               identification_t *me, identification_t *other);
-       /**
-        * Get a private key to create a signature.
-        *
-        * The get_private() method gets a secret private key identified by either
-        * the keyid itself or an id the key belongs to.
-        * The auth parameter contains additional information, such as receipients
-        * trusted CA certs. Auth gets filled with subject and CA certificates
-        * needed to validate a created signature.
-        *
-        * @param type          type of the key to get
-        * @param id            identification the key belongs to
-        * @param auth          auth config, including trusted CA certificates
-        * @return                      private_key_t, NULL if none found
-        */
-       private_key_t* (*get_private)(credential_manager_t *this, key_type_t type,
-                                                                 identification_t *id, auth_cfg_t *auth);
-
-       /**
-        * Create an enumerator over trusted public keys.
-        *
-        * This method gets a an enumerator over trusted public keys to verify a
-        * signature created by id. The auth parameter contains additional
-        * authentication infos, e.g. peer and intermediate certificates.
-        * The resulting enumerator enumerates over public_key_t *, auth_cfg_t *,
-        * where the auth config helper contains rules for constraint checks.
-        *
-        * @param type          type of the key to get
-        * @param id            owner of the key, signer of the signature
-        * @param auth          authentication infos
-        * @return                      enumerator
-        */
-       enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
-                                       key_type_t type, identification_t *id, auth_cfg_t *auth);
-
-       /**
-        * Cache a certificate by invoking cache_cert() on all registerd sets.
-        *
-        * @param cert          certificate to cache
-        */
-       void (*cache_cert)(credential_manager_t *this, certificate_t *cert);
-
-       /**
-        * Flush the certificate cache.
-        *
-        * Only the managers local cache is flushed, but not the sets cache filled
-        * by the cache_cert() method.
-        *
-        * @param type          type of certificate to flush, or CERT_ANY
-        */
-       void (*flush_cache)(credential_manager_t *this, certificate_type_t type);
-
-       /**
-        * Register a credential set to the manager.
-        *
-        * @param set           set to register
-        */
-       void (*add_set)(credential_manager_t *this, credential_set_t *set);
-
-       /**
-        * Unregister a credential set from the manager.
-        *
-        * @param set           set to unregister
-        */
-       void (*remove_set)(credential_manager_t *this, credential_set_t *set);
-
-       /**
-        * Destroy a credential_manager instance.
-        */
-       void (*destroy)(credential_manager_t *this);
-};
-
-/**
- * Create a credential_manager instance.
- */
-credential_manager_t *credential_manager_create();
-
-#endif /** CREDENTIAL_MANAGER_H_ @}*/
diff --git a/src/libcharon/credentials/credential_set.h b/src/libcharon/credentials/credential_set.h
deleted file mode 100644 (file)
index 274eb3f..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 credential_set credential_set
- * @{ @ingroup ccredentials
- */
-
-#ifndef CREDENTIAL_SET_H_
-#define CREDENTIAL_SET_H_
-
-#include <credentials/keys/public_key.h>
-#include <credentials/keys/shared_key.h>
-#include <credentials/certificates/certificate.h>
-
-typedef struct credential_set_t credential_set_t;
-
-/**
- * A set of credentials.
- *
- * Contains private keys, shared keys and different kinds of certificates.
- * Enumerators are used because queries might return multiple matches.
- * Filter parameters restrict enumeration over specific items only.
- * See credential_manager_t for an overview of the credential framework.
- *
- * A credential set enumerator may not block the credential set, i.e. multiple
- * threads must be able to hold multiple enumerators, as the credential manager
- * is higly parallelized. The best way to achieve this is by using shared
- * read locks for the enumerators only. Otherwiese deadlocks will occur.
- * The writing cache_cert() routine is called by the manager only if no
- * enumerator is alive, so it is save to use a write lock there.
- */
-struct credential_set_t {
-
-       /**
-        * Create an enumerator over private keys (private_key_t).
-        *
-        * The id is either a key identifier of the requested key, or an identity
-        * of the key owner.
-        *
-        * @param type          type of requested private key
-        * @param id            key identifier/owner
-        * @return                      enumerator over private_key_t's.
-        */
-       enumerator_t *(*create_private_enumerator)(credential_set_t *this,
-                                               key_type_t type, identification_t *id);
-       /**
-        * Create an enumerator over certificates (certificate_t).
-        *
-        * @param cert          kind of certificate
-        * @param key           kind of key in certificate
-        * @param id            identity (subject) this certificate belongs to
-        * @param trusted       whether the certificate must be trustworthy
-        * @return                      enumerator as described above
-        */
-       enumerator_t *(*create_cert_enumerator)(credential_set_t *this,
-                                               certificate_type_t cert, key_type_t key,
-                                               identification_t *id, bool trusted);
-       /**
-        * Create an enumerator over shared keys (shared_key_t).
-        *
-        * The enumerator enumerates over:
-        *  shared_key_t*, id_match_t me, id_match_t other
-        * But must accept NULL values for the id_matches.
-        *
-        * @param type          kind of requested shared key
-        * @param me            own identity
-        * @param other         other identity who owns that secret
-        * @return                      enumerator as described above
-        */
-       enumerator_t *(*create_shared_enumerator)(credential_set_t *this,
-                                               shared_key_type_t type,
-                                               identification_t *me, identification_t *other);
-
-       /**
-        * Create an enumerator over certificate distribution points.
-        *
-        * @param type          type of the certificate to get a CDP
-        * @param id            identification of the distributed certificate
-        * @return                      an enumerator over CDPs as char*
-        */
-       enumerator_t *(*create_cdp_enumerator)(credential_set_t *this,
-                                               certificate_type_t type, identification_t *id);
-
-       /**
-        * Cache a certificate in the credential set.
-        *
-        * The caching policy is implementation dependent, the sets may cache the
-        * certificate in-memory, persistent on disk or not at all.
-        *
-        * @param cert          certificate to cache
-        */
-       void (*cache_cert)(credential_set_t *this, certificate_t *cert);
-};
-
-#endif /** CREDENTIAL_SET_H_ @}*/
diff --git a/src/libcharon/credentials/sets/auth_cfg_wrapper.c b/src/libcharon/credentials/sets/auth_cfg_wrapper.c
deleted file mode 100644 (file)
index 82e33d2..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * 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 <daemon.h>
-
-#include "auth_cfg_wrapper.h"
-
-typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t;
-
-/**
- * private data of auth_cfg_wrapper
- */
-struct private_auth_cfg_wrapper_t {
-
-       /**
-        * public functions
-        */
-       auth_cfg_wrapper_t public;
-
-       /**
-        * wrapped auth info
-        */
-       auth_cfg_t *auth;
-};
-
-/**
- * enumerator for auth_cfg_wrapper_t.create_cert_enumerator()
- */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** inner enumerator from auth_cfg */
-       enumerator_t *inner;
-       /** wrapped auth round */
-       auth_cfg_t *auth;
-       /** enumerated cert type */
-       certificate_type_t cert;
-       /** enumerated key type */
-       key_type_t key;
-       /** enumerated id */
-       identification_t *id;
-} wrapper_enumerator_t;
-
-/**
- * Tries to fetch a certificate that was supplied as "Hash and URL"
- * (replaces rule type and value in place).
- */
-static bool fetch_cert(wrapper_enumerator_t *enumerator,
-                                          auth_rule_t *rule, void **value)
-{
-       char *url = (char*)*value;
-       if (!url)
-       {
-               /* fetching the certificate previously failed */
-               return FALSE;
-       }
-
-       chunk_t data;
-       certificate_t *cert;
-
-       DBG1(DBG_CFG, "  fetching certificate from '%s' ...", url);
-       if (lib->fetcher->fetch(lib->fetcher, url, &data, FETCH_END) != SUCCESS)
-       {
-               DBG1(DBG_CFG, "  fetching certificate failed");
-               /* we set the item to NULL, so we can skip it */
-               enumerator->auth->replace(enumerator->auth, enumerator->inner,
-                                                                 *rule, NULL);
-               return FALSE;
-       }
-
-       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-                                                         BUILD_BLOB_ASN1_DER, data, BUILD_END);
-       free(data.ptr);
-
-       if (!cert)
-       {
-               DBG1(DBG_CFG, "  parsing fetched certificate failed");
-               /* we set the item to NULL, so we can skip it */
-               enumerator->auth->replace(enumerator->auth, enumerator->inner,
-                                                                 *rule, NULL);
-               return FALSE;
-       }
-
-       DBG1(DBG_CFG, "  fetched certificate \"%Y\"", cert->get_subject(cert));
-       charon->credentials->cache_cert(charon->credentials, cert);
-
-       if (*rule == AUTH_HELPER_IM_HASH_URL)
-       {
-               *rule = AUTH_HELPER_IM_CERT;
-       }
-       else
-       {
-               *rule = AUTH_HELPER_SUBJECT_CERT;
-       }
-       *value = cert;
-       enumerator->auth->replace(enumerator->auth, enumerator->inner,
-                                                         *rule, cert->get_ref(cert));
-       return TRUE;
-}
-
-/**
- * enumerate function for wrapper_enumerator_t
- */
-static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
-{
-       auth_rule_t rule;
-       certificate_t *current;
-       public_key_t *public;
-
-       while (this->inner->enumerate(this->inner, &rule, &current))
-       {
-               if (rule == AUTH_HELPER_IM_HASH_URL ||
-                       rule == AUTH_HELPER_SUBJECT_HASH_URL)
-               {       /* on-demand fetching of hash and url certificates */
-                       if (!fetch_cert(this, &rule, (void**)&current))
-                       {
-                               continue;
-                       }
-               }
-               else if (rule != AUTH_HELPER_SUBJECT_CERT &&
-                                rule != AUTH_HELPER_IM_CERT)
-               {       /* handle only HELPER certificates */
-                       continue;
-               }
-               if (this->cert != CERT_ANY && this->cert != current->get_type(current))
-               {       /* CERT type requested, but does not match */
-                       continue;
-               }
-               public = current->get_public_key(current);
-               if (this->key != KEY_ANY && !public)
-               {       /* key type requested, but no public key */
-                       DESTROY_IF(public);
-                       continue;
-               }
-               if (this->key != KEY_ANY && public && this->key != public->get_type(public))
-               {       /* key type requested, but public key has another type */
-                       DESTROY_IF(public);
-                       continue;
-               }
-               DESTROY_IF(public);
-               if (this->id && !current->has_subject(current, this->id))
-               {       /* subject requested, but does not match */
-                       continue;
-               }
-               *cert = current;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * destroy function for wrapper_enumerator_t
- */
-static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
-{
-       this->inner->destroy(this->inner);
-       free(this);
-}
-
-/**
- * implementation of auth_cfg_wrapper_t.set.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
-                                                                          certificate_type_t cert, key_type_t key,
-                                                                          identification_t *id, bool trusted)
-{
-       wrapper_enumerator_t *enumerator;
-
-       if (trusted)
-       {
-               return NULL;
-       }
-       enumerator = malloc_thing(wrapper_enumerator_t);
-       enumerator->auth = this->auth;
-       enumerator->cert = cert;
-       enumerator->key = key;
-       enumerator->id = id;
-       enumerator->inner = this->auth->create_enumerator(this->auth);
-       enumerator->public.enumerate = (void*)enumerate;
-       enumerator->public.destroy = (void*)wrapper_enumerator_destroy;
-       return &enumerator->public;
-}
-
-/**
- * Implementation of auth_cfg_wrapper_t.destroy
- */
-static void destroy(private_auth_cfg_wrapper_t *this)
-{
-       free(this);
-}
-
-/*
- * see header file
- */
-auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
-{
-       private_auth_cfg_wrapper_t *this = malloc_thing(private_auth_cfg_wrapper_t);
-
-       this->public.set.create_private_enumerator = (void*)return_null;
-       this->public.set.create_cert_enumerator = (void*)create_enumerator;
-       this->public.set.create_shared_enumerator = (void*)return_null;
-       this->public.set.create_cdp_enumerator = (void*)return_null;
-       this->public.set.cache_cert = (void*)nop;
-       this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy;
-
-       this->auth = auth;
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/credentials/sets/auth_cfg_wrapper.h b/src/libcharon/credentials/sets/auth_cfg_wrapper.h
deleted file mode 100644 (file)
index 7653fcd..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 auth_cfg_wrapper auth_cfg_wrapper
- * @{ @ingroup sets
- */
-
-#ifndef AUTH_CFG_WRAPPER_H_
-#define AUTH_CFG_WRAPPER_H_
-
-#include <config/auth_cfg.h>
-#include <credentials/credential_set.h>
-
-typedef struct auth_cfg_wrapper_t auth_cfg_wrapper_t;
-
-/**
- * A wrapper around auth_cfg_t to handle it as a credential set.
- */
-struct auth_cfg_wrapper_t {
-
-       /**
-        * implements credential_set_t
-        */
-       credential_set_t set;
-
-       /**
-        * Destroy a auth_cfg_wrapper instance.
-        */
-       void (*destroy)(auth_cfg_wrapper_t *this);
-};
-
-/**
- * Create a auth_cfg_wrapper instance.
- *
- * @param auth         the wrapped auth info
- * @return                     wrapper around auth
- */
-auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth);
-
-#endif /** AUTH_CFG_WRAPPER_H_ @}*/
diff --git a/src/libcharon/credentials/sets/cert_cache.c b/src/libcharon/credentials/sets/cert_cache.c
deleted file mode 100644 (file)
index 176accc..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 "cert_cache.h"
-
-#include <time.h>
-#include <sched.h>
-
-#include <daemon.h>
-#include <threading/rwlock.h>
-#include <utils/linked_list.h>
-
-/** cache size, a power of 2 for fast modulo */
-#define CACHE_SIZE 32
-
-/** attempts to acquire a cache lock */
-#define REPLACE_TRIES 5
-
-typedef struct private_cert_cache_t private_cert_cache_t;
-typedef struct relation_t relation_t;
-
-/**
- * A trusted relation between subject and issuer
- */
-struct relation_t {
-
-       /**
-        * subject of this relation
-        */
-       certificate_t *subject;
-
-       /**
-        * issuer of this relation
-        */
-       certificate_t *issuer;
-
-       /**
-        * Cache hits
-        */
-       u_int hits;
-
-       /**
-        * Lock for this relation
-        */
-       rwlock_t *lock;
-};
-
-/**
- * private data of cert_cache
- */
-struct private_cert_cache_t {
-
-       /**
-        * public functions
-        */
-       cert_cache_t public;
-
-       /**
-        * array of trusted subject-issuer relations
-        */
-       relation_t relations[CACHE_SIZE];
-};
-
-/**
- * Cache relation in a free slot/replace an other
- */
-static void cache(private_cert_cache_t *this,
-                                 certificate_t *subject, certificate_t *issuer)
-{
-       relation_t *rel;
-       int i, offset, try;
-       u_int total_hits = 0;
-
-       /* check for a unused relation slot first */
-       for (i = 0; i < CACHE_SIZE; i++)
-       {
-               rel = &this->relations[i];
-
-               if (!rel->subject && rel->lock->try_write_lock(rel->lock))
-               {
-                       /* double-check having lock */
-                       if (!rel->subject)
-                       {
-                               rel->subject = subject->get_ref(subject);
-                               rel->issuer = issuer->get_ref(issuer);
-                               return rel->lock->unlock(rel->lock);
-                       }
-                       rel->lock->unlock(rel->lock);
-               }
-               total_hits += rel->hits;
-       }
-       /* run several attempts to replace a random slot, never block. */
-       for (try = 0; try < REPLACE_TRIES; try++)
-       {
-               /* replace a random relation */
-               offset = random();
-               for (i = 0; i < CACHE_SIZE; i++)
-               {
-                       rel = &this->relations[(i + offset) % CACHE_SIZE];
-
-                       if (rel->hits > total_hits / CACHE_SIZE)
-                       {       /* skip often used slots */
-                               continue;
-                       }
-                       if (rel->lock->try_write_lock(rel->lock))
-                       {
-                               if (rel->subject)
-                               {
-                                       rel->subject->destroy(rel->subject);
-                                       rel->issuer->destroy(rel->issuer);
-                               }
-                               rel->subject = subject->get_ref(subject);
-                               rel->issuer = issuer->get_ref(issuer);
-                               rel->hits = 0;
-                               return rel->lock->unlock(rel->lock);
-                       }
-               }
-               /* give other threads a chance to release locks */
-               sched_yield();
-       }
-}
-
-/**
- * Implementation of cert_cache_t.issued_by.
- */
-static bool issued_by(private_cert_cache_t *this,
-                                         certificate_t *subject, certificate_t *issuer)
-{
-       relation_t *found = NULL, *current;
-       int i;
-
-       for (i = 0; i < CACHE_SIZE; i++)
-       {
-               current = &this->relations[i];
-
-               current->lock->read_lock(current->lock);
-               if (current->subject)
-               {
-                       /* check for equal issuer */
-                       if (issuer->equals(issuer, current->issuer))
-                       {
-                               /* reuse issuer instance in cache() */
-                               issuer = current->issuer;
-                               if (subject->equals(subject, current->subject))
-                               {
-                                       /* write hit counter is not locked, but not critical */
-                                       current->hits++;
-                                       found = current;
-                               }
-                       }
-               }
-               current->lock->unlock(current->lock);
-               if (found)
-               {
-                       return TRUE;
-               }
-       }
-       /* no cache hit, check and cache signature */
-       if (subject->issued_by(subject, issuer))
-       {
-               cache(this, subject, issuer);
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * certificate enumerator implemenation
- */
-typedef struct {
-       /** implements enumerator_t interface */
-       enumerator_t public;
-       /** type of requested certificate */
-       certificate_type_t cert;
-       /** type of requested key */
-       key_type_t key;
-       /** ID to get a cert for */
-       identification_t *id;
-       /** cache */
-       relation_t *relations;
-       /** current position in array cache */
-       int index;
-       /** currently locked relation */
-       int locked;
-} cert_enumerator_t;
-
-/**
- * filter function for certs enumerator
- */
-static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out)
-{
-       public_key_t *public;
-       relation_t *rel;
-
-       if (this->locked >= 0)
-       {
-               rel = &this->relations[this->locked];
-               rel->lock->unlock(rel->lock);
-               this->locked = -1;
-       }
-
-       while (++this->index < CACHE_SIZE)
-       {
-               rel = &this->relations[this->index];
-               rel->lock->read_lock(rel->lock);
-               this->locked = this->index;
-               if (rel->subject)
-               {
-                       /* CRL lookup is done using issuer/authkeyidentifier */
-                       if (this->key == KEY_ANY && this->id &&
-                               (this->cert == CERT_ANY || this->cert == CERT_X509_CRL) &&
-                               rel->subject->get_type(rel->subject) == CERT_X509_CRL &&
-                               rel->subject->has_issuer(rel->subject, this->id))
-                       {
-                               *out = rel->subject;
-                               return TRUE;
-                       }
-                       if ((this->cert == CERT_ANY ||
-                                rel->subject->get_type(rel->subject) == this->cert) &&
-                               (!this->id || rel->subject->has_subject(rel->subject, this->id)))
-                       {
-                               if (this->key == KEY_ANY)
-                               {
-                                       *out = rel->subject;
-                                       return TRUE;
-                               }
-                               public = rel->subject->get_public_key(rel->subject);
-                               if (public)
-                               {
-                                       if (public->get_type(public) == this->key)
-                                       {
-                                               public->destroy(public);
-                                               *out = rel->subject;
-                                               return TRUE;
-                                       }
-                                       public->destroy(public);
-                               }
-                       }
-               }
-               this->locked = -1;
-               rel->lock->unlock(rel->lock);
-       }
-       return FALSE;
-}
-
-/**
- * clean up enumeration data
- */
-static void cert_enumerator_destroy(cert_enumerator_t *this)
-{
-       relation_t *rel;
-
-       if (this->locked >= 0)
-       {
-               rel = &this->relations[this->locked];
-               rel->lock->unlock(rel->lock);
-       }
-       free(this);
-}
-
-/**
- * implementation of credential_set_t.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_cert_cache_t *this,
-                                                                          certificate_type_t cert, key_type_t key,
-                                                                          identification_t *id, bool trusted)
-{
-       cert_enumerator_t *enumerator;
-
-       if (trusted)
-       {
-               return NULL;
-       }
-       enumerator = malloc_thing(cert_enumerator_t);
-       enumerator->public.enumerate = (void*)cert_enumerate;
-       enumerator->public.destroy = (void*)cert_enumerator_destroy;
-       enumerator->cert = cert;
-       enumerator->key = key;
-       enumerator->id = id;
-       enumerator->relations = this->relations;
-       enumerator->index = -1;
-       enumerator->locked = -1;
-
-       return &enumerator->public;
-}
-
-/**
- * Implementation of cert_cache_t.flush.
- */
-static void flush(private_cert_cache_t *this, certificate_type_t type)
-{
-       relation_t *rel;
-       int i;
-
-       for (i = 0; i < CACHE_SIZE; i++)
-       {
-               rel = &this->relations[i];
-               if (!rel->subject)
-               {
-                       continue;
-               }
-               /* check with cheap read lock first */
-               if (type != CERT_ANY)
-               {
-                       rel->lock->read_lock(rel->lock);
-                       if (!rel->subject || type != rel->subject->get_type(rel->subject))
-                       {
-                               rel->lock->unlock(rel->lock);
-                               continue;
-                       }
-                       rel->lock->unlock(rel->lock);
-               }
-               /* double check in write lock */
-               rel->lock->write_lock(rel->lock);
-               if (rel->subject)
-               {
-                       if (type == CERT_ANY || type == rel->subject->get_type(rel->subject))
-                       {
-                               rel->subject->destroy(rel->subject);
-                               rel->issuer->destroy(rel->issuer);
-                               rel->subject = NULL;
-                               rel->issuer = NULL;
-                               rel->hits = 0;
-                       }
-               }
-               rel->lock->unlock(rel->lock);
-       }
-}
-
-/**
- * Implementation of cert_cache_t.destroy
- */
-static void destroy(private_cert_cache_t *this)
-{
-       relation_t *rel;
-       int i;
-
-       for (i = 0; i < CACHE_SIZE; i++)
-       {
-               rel = &this->relations[i];
-               if (rel->subject)
-               {
-                       rel->subject->destroy(rel->subject);
-                       rel->issuer->destroy(rel->issuer);
-               }
-               rel->lock->destroy(rel->lock);
-       }
-       free(this);
-}
-
-/*
- * see header file
- */
-cert_cache_t *cert_cache_create()
-{
-       private_cert_cache_t *this;
-       int i;
-
-       this = malloc_thing(private_cert_cache_t);
-       this->public.set.create_private_enumerator = (void*)return_null;
-       this->public.set.create_cert_enumerator = (void*)create_enumerator;
-       this->public.set.create_shared_enumerator = (void*)return_null;
-       this->public.set.create_cdp_enumerator = (void*)return_null;
-       this->public.set.cache_cert = (void*)nop;
-       this->public.issued_by = (bool(*)(cert_cache_t*, certificate_t *subject, certificate_t *issuer))issued_by;
-       this->public.flush = (void(*)(cert_cache_t*, certificate_type_t type))flush;
-       this->public.destroy = (void(*)(cert_cache_t*))destroy;
-
-       for (i = 0; i < CACHE_SIZE; i++)
-       {
-               this->relations[i].subject = NULL;
-               this->relations[i].issuer = NULL;
-               this->relations[i].hits = 0;
-               this->relations[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-       }
-       return &this->public;
-}
-
diff --git a/src/libcharon/credentials/sets/cert_cache.h b/src/libcharon/credentials/sets/cert_cache.h
deleted file mode 100644 (file)
index d272186..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 cert_cache cert_cache
- * @{ @ingroup sets
- */
-
-#ifndef CERT_CACHE_H_
-#define CERT_CACHE_H_
-
-#include <credentials/credential_set.h>
-
-typedef struct cert_cache_t cert_cache_t;
-
-/**
- * Certificate signature verification and certificate cache.
- *
- * This cache serves all certificates seen in its issued_by method
- * and serves them as untrusted through the credential set interface. Further,
- * it caches valid subject-issuer relationships to speed up the issued_by
- * method.
- */
-struct cert_cache_t {
-
-       /**
-        * Implements credential_set_t.
-        */
-       credential_set_t set;
-
-       /**
-        * Caching wrapper around certificate_t.issued_by.
-        *
-        * @param subject               certificate to verify
-        * @param issuer                issuing certificate to verify subject
-        * @return                              TRUE if subject issued by issuer
-        */
-       bool (*issued_by)(cert_cache_t *this,
-                                         certificate_t *subject, certificate_t *issuer);
-
-       /**
-        * Flush the certificate cache.
-        *
-        * @param type                  type of certificate to flush, or CERT_ANY
-        */
-       void (*flush)(cert_cache_t *this, certificate_type_t type);
-
-       /**
-        * Destroy a cert_cache instance.
-        */
-       void (*destroy)(cert_cache_t *this);
-};
-
-/**
- * Create a cert_cache instance.
- */
-cert_cache_t *cert_cache_create();
-
-#endif /** CERT_CACHE_H_ @}*/
diff --git a/src/libcharon/credentials/sets/ocsp_response_wrapper.c b/src/libcharon/credentials/sets/ocsp_response_wrapper.c
deleted file mode 100644 (file)
index 8207920..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 "ocsp_response_wrapper.h"
-
-typedef struct private_ocsp_response_wrapper_t private_ocsp_response_wrapper_t;
-
-/**
- * private data of ocsp_response_wrapper
- */
-struct private_ocsp_response_wrapper_t {
-
-       /**
-        * public functions
-        */
-       ocsp_response_wrapper_t public;
-
-       /**
-        * wrapped OCSP response
-        */
-       ocsp_response_t *response;
-};
-
-/**
- * enumerator for ocsp_response_wrapper_t.create_cert_enumerator()
- */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** enumerator over ocsp response */
-       enumerator_t *inner;
-       /** type of cert */
-       certificate_type_t cert;
-       /** type of key */
-       key_type_t key;
-       /** filtering identity */
-       identification_t *id;
-} wrapper_enumerator_t;
-
-/**
- * enumerate function wrapper_enumerator_t
- */
-static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
-{
-       certificate_t *current;
-       public_key_t *public;
-
-       while (this->inner->enumerate(this->inner, &current))
-       {
-               if (this->cert != CERT_ANY && this->cert != current->get_type(current))
-               {       /* CERT type requested, but does not match */
-                       continue;
-               }
-               public = current->get_public_key(current);
-               if (this->key != KEY_ANY && !public)
-               {       /* key type requested, but no public key */
-                       DESTROY_IF(public);
-                       continue;
-               }
-               if (this->key != KEY_ANY && public && this->key != public->get_type(public))
-               {       /* key type requested, but public key has another type */
-                       DESTROY_IF(public);
-                       continue;
-               }
-               DESTROY_IF(public);
-               if (this->id && !current->has_subject(current, this->id))
-               {       /* subject requested, but does not match */
-                       continue;
-               }
-               *cert = current;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * destroy function for wrapper_enumerator_t
- */
-static void enumerator_destroy(wrapper_enumerator_t *this)
-{
-       this->inner->destroy(this->inner);
-       free(this);
-}
-
-/**
- * implementation of ocsp_response_wrapper_t.set.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_ocsp_response_wrapper_t *this,
-                                                                          certificate_type_t cert, key_type_t key,
-                                                                          identification_t *id, bool trusted)
-{
-       wrapper_enumerator_t *enumerator;
-
-       if (trusted)
-       {
-               return NULL;
-       }
-
-       enumerator = malloc_thing(wrapper_enumerator_t);
-       enumerator->cert = cert;
-       enumerator->key = key;
-       enumerator->id = id;
-       enumerator->inner = this->response->create_cert_enumerator(this->response);
-       enumerator->public.enumerate = (void*)enumerate;
-       enumerator->public.destroy = (void*)enumerator_destroy;
-       return &enumerator->public;
-}
-
-/**
- * Implementation of ocsp_response_wrapper_t.destroy
- */
-static void destroy(private_ocsp_response_wrapper_t *this)
-{
-       free(this);
-}
-
-/*
- * see header file
- */
-ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response)
-{
-       private_ocsp_response_wrapper_t *this = malloc_thing(private_ocsp_response_wrapper_t);
-
-       this->public.set.create_private_enumerator = (void*)return_null;
-       this->public.set.create_cert_enumerator = (void*)create_enumerator;
-       this->public.set.create_shared_enumerator = (void*)return_null;
-       this->public.set.create_cdp_enumerator = (void*)return_null;
-       this->public.set.cache_cert = (void*)nop;
-       this->public.destroy = (void(*)(ocsp_response_wrapper_t*))destroy;
-
-       this->response = response;
-
-       return &this->public;
-}
-
diff --git a/src/libcharon/credentials/sets/ocsp_response_wrapper.h b/src/libcharon/credentials/sets/ocsp_response_wrapper.h
deleted file mode 100644 (file)
index dc4b451..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 ocsp_response_wrapper ocsp_response_wrapper
- * @{ @ingroup sets
- */
-
-#ifndef OCSP_RESPONSE_WRAPPER_H_
-#define OCSP_RESPONSE_WRAPPER_H_
-
-#include <credentials/credential_set.h>
-#include <credentials/certificates/ocsp_response.h>
-
-typedef struct ocsp_response_wrapper_t ocsp_response_wrapper_t;
-
-/**
- * A wrapper around ocsp_response_t to handle it like a credential set.
- */
-struct ocsp_response_wrapper_t {
-
-       /**
-        * implements credential_set_t
-        */
-       credential_set_t set;
-
-       /**
-        * Destroy a ocsp_response_wrapper instance.
-        */
-       void (*destroy)(ocsp_response_wrapper_t *this);
-};
-
-/**
- * Create a ocsp_response_wrapper instance.
- *
- * @param response     the wrapped OCSP response
- * @return                     wrapper around response
- */
-ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response);
-
-#endif /** OCSP_RESPONSE_WRAPPER_H_ @}*/
index e1aa03e..c022702 100644 (file)
@@ -122,7 +122,6 @@ static void destroy(private_daemon_t *this)
        DESTROY_IF(this->public.mediation_manager);
 #endif /* ME */
        DESTROY_IF(this->public.backends);
-       DESTROY_IF(this->public.credentials);
        DESTROY_IF(this->public.socket);
        /* wait until all threads are gone */
        DESTROY_IF(this->public.processor);
@@ -359,7 +358,6 @@ METHOD(daemon_t, initialize, bool,
        /* load secrets, ca certificates and crls */
        this->public.processor = processor_create();
        this->public.scheduler = scheduler_create();
-       this->public.credentials = credential_manager_create();
        this->public.controller = controller_create();
        this->public.eap = eap_manager_create();
        this->public.sim = sim_manager_create();
index 9b6d970..38f0256 100644 (file)
  * @defgroup control control
  * @ingroup libcharon
  *
- * @defgroup ccredentials credentials
- * @ingroup libcharon
- *
- * @defgroup sets sets
- * @ingroup ccredentials
- *
  * @defgroup encoding encoding
  * @ingroup libcharon
  *
@@ -156,7 +150,6 @@ typedef struct daemon_t daemon_t;
 #include <sa/ike_sa_manager.h>
 #include <sa/trap_manager.h>
 #include <config/backend_manager.h>
-#include <credentials/credential_manager.h>
 #include <sa/authenticators/eap/eap_manager.h>
 #include <sa/authenticators/eap/sim_manager.h>
 
@@ -206,11 +199,6 @@ struct daemon_t {
        backend_manager_t *backends;
 
        /**
-        * Manager for the credential backends
-        */
-       credential_manager_t *credentials;
-
-       /**
         * The Sender-Thread.
         */
        sender_t *sender;
index 0e7e950..e2c8572 100644 (file)
@@ -62,7 +62,7 @@ METHOD(plugin_t, destroy, void,
 {
        hydra->attributes->remove_handler(hydra->attributes,
                                                                          &this->handler->handler);
-       charon->credentials->remove_set(charon->credentials, &this->creds->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
        charon->bus->remove_listener(charon->bus, &this->logger->listener);
        this->creds->destroy(this->creds);
        this->handler->destroy(this->handler);
@@ -88,7 +88,7 @@ plugin_t *android_plugin_create()
        );
 
        charon->bus->add_listener(charon->bus, &this->logger->listener);
-       charon->credentials->add_set(charon->credentials, &this->creds->set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
        hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
 
        this->service = android_service_create(this->creds);
index 9817fff..a9767ad 100644 (file)
@@ -52,8 +52,7 @@ bool eap_aka_3gpp2_get_k(identification_t *id, char k[AKA_K_LEN])
        shared_key_t *shared;
        chunk_t key;
 
-       shared = charon->credentials->get_shared(charon->credentials,
-                                                                                        SHARED_EAP, id, NULL);
+       shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, id, NULL);
        if (shared == NULL)
        {
                return FALSE;
index c7f55fa..f641ad1 100644 (file)
@@ -168,8 +168,8 @@ static status_t process_peer(private_eap_gtc_t *this,
        chunk_t key;
        size_t len;
 
-       shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
-                                                                                        this->peer, this->server);
+       shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP,
+                                                                         this->peer, this->server);
        if (shared == NULL)
        {
                DBG1(DBG_IKE, "no EAP key found for '%Y' - '%Y'",
index 0eda8f7..3554ae1 100644 (file)
@@ -85,8 +85,7 @@ static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response,
        chunk_t concat;
        hasher_t *hasher;
 
-       shared = charon->credentials->get_shared(charon->credentials, SHARED_EAP,
-                                                                                        me, other);
+       shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, me, other);
        if (shared == NULL)
        {
                DBG1(DBG_IKE, "no EAP key found for hosts '%Y' - '%Y'", me, other);
index 5228c6c..3cd8d99 100644 (file)
@@ -614,8 +614,7 @@ static bool get_nt_hash(private_eap_mschapv2_t *this, identification_t *me,
        chunk_t password;
 
        /* try to find a stored NT_HASH first */
-       shared = charon->credentials->get_shared(charon->credentials,
-                                                                                       SHARED_NT_HASH, me, other);
+       shared = lib->credmgr->get_shared(lib->credmgr, SHARED_NT_HASH, me, other);
        if (shared )
        {
                *nt_hash = chunk_clone(shared->get_key(shared));
@@ -624,8 +623,7 @@ static bool get_nt_hash(private_eap_mschapv2_t *this, identification_t *me,
        }
 
        /* fallback to plaintext password */
-       shared = charon->credentials->get_shared(charon->credentials,
-                                                                                       SHARED_EAP, me, other);
+       shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, me, other);
        if (shared)
        {
                password = ascii_to_unicode(shared->get_key(shared));
index 89daa4f..882cfd2 100644 (file)
@@ -211,7 +211,7 @@ static void setup_tunnel(private_ha_tunnel_t *this,
        this->creds.public.create_cdp_enumerator = (void*)return_null;
        this->creds.public.cache_cert = (void*)nop;
 
-       charon->credentials->add_set(charon->credentials, &this->creds.public);
+       lib->credmgr->add_set(lib->credmgr, &this->creds.public);
 
        /* create config and backend */
        ike_cfg = ike_cfg_create(FALSE, FALSE, local, IKEV2_UDP_PORT,
@@ -270,7 +270,7 @@ static void destroy(private_ha_tunnel_t *this)
        }
        if (this->creds.key)
        {
-               charon->credentials->remove_set(charon->credentials, &this->creds.public);
+               lib->credmgr->remove_set(lib->credmgr, &this->creds.public);
                this->creds.key->destroy(this->creds.key);
        }
        this->creds.local->destroy(this->creds.local);
index 46145b8..15dbccb 100644 (file)
@@ -158,7 +158,7 @@ static void destroy(private_load_tester_plugin_t *this)
        charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface,
                                                (kernel_ipsec_constructor_t)load_tester_ipsec_create);
        charon->backends->remove_backend(charon->backends, &this->config->backend);
-       charon->credentials->remove_set(charon->credentials, &this->creds->credential_set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
        charon->bus->remove_listener(charon->bus, &this->listener->listener);
        this->config->destroy(this->config);
        this->creds->destroy(this->creds);
@@ -209,7 +209,7 @@ plugin_t *load_tester_plugin_create()
        this->creds = load_tester_creds_create();
        this->listener = load_tester_listener_create(shutdown_on);
        charon->backends->add_backend(charon->backends, &this->config->backend);
-       charon->credentials->add_set(charon->credentials, &this->creds->credential_set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
        charon->bus->add_listener(charon->bus, &this->listener->listener);
 
        if (lib->settings->get_bool(lib->settings,
index 397168d..6befbf4 100644 (file)
@@ -61,7 +61,7 @@ static void destroy(private_medcli_plugin_t *this)
 {
        charon->bus->remove_listener(charon->bus, &this->listener->listener);
        charon->backends->remove_backend(charon->backends, &this->config->backend);
-       charon->credentials->remove_set(charon->credentials, &this->creds->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
        this->listener->destroy(this->listener);
        this->config->destroy(this->config);
        this->creds->destroy(this->creds);
@@ -100,7 +100,7 @@ plugin_t *medcli_plugin_create()
        this->config = medcli_config_create(this->db);
        this->listener = medcli_listener_create(this->db);
 
-       charon->credentials->add_set(charon->credentials, &this->creds->set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
        charon->backends->add_backend(charon->backends, &this->config->backend);
        charon->bus->add_listener(charon->bus, &this->listener->listener);
 
index 262d26d..c150346 100644 (file)
@@ -54,7 +54,7 @@ struct private_medsrv_plugin_t {
 static void destroy(private_medsrv_plugin_t *this)
 {
        charon->backends->remove_backend(charon->backends, &this->config->backend);
-       charon->credentials->remove_set(charon->credentials, &this->creds->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
        this->config->destroy(this->config);
        this->creds->destroy(this->creds);
        this->db->destroy(this->db);
@@ -91,7 +91,7 @@ plugin_t *medsrv_plugin_create()
        this->creds = medsrv_creds_create(this->db);
        this->config = medsrv_config_create(this->db);
 
-       charon->credentials->add_set(charon->credentials, &this->creds->set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
        charon->backends->add_backend(charon->backends, &this->config->backend);
 
        return &this->public.plugin;
index 6087f65..250e6f7 100644 (file)
@@ -84,7 +84,7 @@ static void destroy(private_nm_plugin_t *this)
        {
                g_object_unref(this->plugin);
        }
-       charon->credentials->remove_set(charon->credentials, &this->creds->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
        hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
        this->creds->destroy(this->creds);
        this->handler->destroy(this->handler);
@@ -110,7 +110,7 @@ plugin_t *nm_plugin_create()
        this->creds = nm_creds_create();
        this->handler = nm_handler_create();
        hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
-       charon->credentials->add_set(charon->credentials, &this->creds->set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->set);
        this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
        if (!this->plugin)
        {
index e2d2d63..7b0a198 100644 (file)
@@ -59,7 +59,7 @@ struct private_sql_plugin_t {
 static void destroy(private_sql_plugin_t *this)
 {
        charon->backends->remove_backend(charon->backends, &this->config->backend);
-       charon->credentials->remove_set(charon->credentials, &this->cred->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
        charon->bus->remove_listener(charon->bus, &this->logger->listener);
        this->config->destroy(this->config);
        this->cred->destroy(this->cred);
@@ -99,7 +99,7 @@ plugin_t *sql_plugin_create()
        this->logger = sql_logger_create(this->db);
 
        charon->backends->add_backend(charon->backends, &this->config->backend);
-       charon->credentials->add_set(charon->credentials, &this->cred->set);
+       lib->credmgr->add_set(lib->credmgr, &this->cred->set);
        charon->bus->add_listener(charon->bus, &this->logger->listener);
 
        return &this->public.plugin;
index 0799584..b0d9867 100644 (file)
@@ -307,7 +307,7 @@ static void del(private_stroke_ca_t *this, stroke_msg_t *msg)
        }
        ca_section_destroy(ca);
 
-       charon->credentials->flush_cache(charon->credentials, CERT_ANY);
+       lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
 }
 
 /**
index 4697e5f..6170694 100644 (file)
@@ -399,8 +399,8 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
        if (ca)
        {
                identity = identification_create_from_string(ca);
-               certificate = charon->credentials->get_cert(charon->credentials,
-                                                                                       CERT_X509, KEY_ANY, identity, TRUE);
+               certificate = lib->credmgr->get_cert(lib->credmgr, CERT_X509,
+                                                                                        KEY_ANY, identity, TRUE);
                identity->destroy(identity);
                if (certificate)
                {
index bc9fc02..3a2e97b 100644 (file)
@@ -576,9 +576,8 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
 static linked_list_t* create_unique_cert_list(certificate_type_t type)
 {
        linked_list_t *list = linked_list_create();
-       enumerator_t *enumerator = charon->credentials->create_cert_enumerator(
-                                                                       charon->credentials, type, KEY_ANY,
-                                                                       NULL, FALSE);
+       enumerator_t *enumerator = lib->credmgr->create_cert_enumerator(
+                                                                       lib->credmgr, type, KEY_ANY, NULL, FALSE);
        certificate_t *cert;
 
        while (enumerator->enumerate(enumerator, (void**)&cert))
@@ -631,7 +630,7 @@ static void list_public_key(public_key_t *public, FILE *out)
        {
                id = identification_create_from_encoding(ID_KEY_ID, keyid);
                auth = auth_cfg_create();
-               private = charon->credentials->get_private(charon->credentials,
+               private = lib->credmgr->get_private(lib->credmgr,
                                                                        public->get_type(public), id, auth);
                auth->destroy(auth);
                id->destroy(id);
index 56c18da..18afa5a 100644 (file)
@@ -344,8 +344,7 @@ static void stroke_purge(private_stroke_socket_t *this,
 {
        if (msg->purge.flags & PURGE_OCSP)
        {
-               charon->credentials->flush_cache(charon->credentials,
-                                                                                CERT_X509_OCSP_RESPONSE);
+               lib->credmgr->flush_cache(lib->credmgr, CERT_X509_OCSP_RESPONSE);
        }
        if (msg->purge.flags & PURGE_IKE)
        {
@@ -622,8 +621,8 @@ static bool open_socket(private_stroke_socket_t *this)
 static void destroy(private_stroke_socket_t *this)
 {
        this->job->cancel(this->job);
-       charon->credentials->remove_set(charon->credentials, &this->ca->set);
-       charon->credentials->remove_set(charon->credentials, &this->cred->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
+       lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
        charon->backends->remove_backend(charon->backends, &this->config->backend);
        hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
        this->cred->destroy(this->cred);
@@ -657,8 +656,8 @@ stroke_socket_t *stroke_socket_create()
        this->control = stroke_control_create();
        this->list = stroke_list_create(this->attribute);
 
-       charon->credentials->add_set(charon->credentials, &this->ca->set);
-       charon->credentials->add_set(charon->credentials, &this->cred->set);
+       lib->credmgr->add_set(lib->credmgr, &this->ca->set);
+       lib->credmgr->add_set(lib->credmgr, &this->cred->set);
        charon->backends->add_backend(charon->backends, &this->config->backend);
        hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
 
index 742fcf4..4790ef4 100644 (file)
@@ -64,7 +64,7 @@ struct private_uci_plugin_t {
 static void destroy(private_uci_plugin_t *this)
 {
        charon->backends->remove_backend(charon->backends, &this->config->backend);
-       charon->credentials->remove_set(charon->credentials, &this->creds->credential_set);
+       lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
        this->config->destroy(this->config);
        this->creds->destroy(this->creds);
        this->parser->destroy(this->parser);
@@ -86,7 +86,7 @@ plugin_t *uci_plugin_create()
        this->creds = uci_creds_create(this->parser);
        this->control = uci_control_create();
        charon->backends->add_backend(charon->backends, &this->config->backend);
-       charon->credentials->add_set(charon->credentials, &this->creds->credential_set);
+       lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
 
        return &this->public.plugin;
 }
index d6abe7a..c250c35 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <daemon.h>
 #include <library.h>
-#include <config/auth_cfg.h>
+#include <credentials/auth_cfg.h>
 
 
 static chunk_t certchunk = chunk_from_chars(
index 7fd78b0..cc4278c 100644 (file)
@@ -37,8 +37,8 @@ bool test_med_db()
        bool good = FALSE;
 
        id = identification_create_from_encoding(ID_KEY_ID, keyid);
-       enumerator = charon->credentials->create_public_enumerator(
-                                                                       charon->credentials, KEY_ANY, id, NULL);
+       enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
+                                                                                                               KEY_ANY, id, NULL);
        while (enumerator->enumerate(enumerator, &public, &auth))
        {
                good = public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &found);
index 13586a2..cd340e5 100644 (file)
@@ -34,13 +34,6 @@ ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
        "ECDSA-521 signature");
 ENUM_END(auth_method_names, AUTH_ECDSA_521);
 
-ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
-       "any",
-       "public key",
-       "pre-shared key",
-       "EAP",
-);
-
 /**
  * Described in header.
  */
index fff91ed..89178b5 100644 (file)
 #define AUTHENTICATOR_H_
 
 typedef enum auth_method_t auth_method_t;
-typedef enum auth_class_t auth_class_t;
 typedef struct authenticator_t authenticator_t;
 
 #include <library.h>
-#include <config/auth_cfg.h>
+#include <credentials/auth_cfg.h>
 #include <sa/ike_sa.h>
 
 /**
@@ -76,27 +75,6 @@ enum auth_method_t {
 extern enum_name_t *auth_method_names;
 
 /**
- * Class of authentication to use. This is different to auth_method_t in that
- * it does not specify a method, but a class of acceptable methods. The found
- * certificate finally dictates wich method is used.
- */
-enum auth_class_t {
-       /** any class acceptable */
-       AUTH_CLASS_ANY = 0,
-       /** authentication using public keys (RSA, ECDSA) */
-       AUTH_CLASS_PUBKEY = 1,
-       /** authentication using a pre-shared secrets */
-       AUTH_CLASS_PSK = 2,
-       /** authentication using EAP */
-       AUTH_CLASS_EAP = 3,
-};
-
-/**
- * enum strings for auth_class_t
- */
-extern enum_name_t *auth_class_names;
-
-/**
  * Authenticator interface implemented by the various authenticators.
  *
  * An authenticator implementation handles AUTH and EAP payloads. Received
index 91fa530..ad7b92c 100644 (file)
 
 #include "eap_method.h"
 
-ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_GTC,
-       "EAP_IDENTITY",
-       "EAP_NOTIFICATION",
-       "EAP_NAK",
-       "EAP_MD5",
-       "EAP_OTP",
-       "EAP_GTC");
-ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_GTC,
-       "EAP_SIM");
-ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
-       "EAP_AKA");
-ENUM_NEXT(eap_type_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
-       "EAP_MSCHAPV2");
-ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
-       "EAP_RADIUS",
-       "EAP_EXPANDED",
-       "EAP_EXPERIMENTAL");
-ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
-
-ENUM_BEGIN(eap_type_short_names, EAP_IDENTITY, EAP_GTC,
-       "ID",
-       "NTF",
-       "NAK",
-       "MD5",
-       "OTP",
-       "GTC");
-ENUM_NEXT(eap_type_short_names, EAP_SIM, EAP_SIM, EAP_GTC,
-       "SIM");
-ENUM_NEXT(eap_type_short_names, EAP_AKA, EAP_AKA, EAP_SIM,
-       "AKA");
-ENUM_NEXT(eap_type_short_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
-       "MSCHAPV2");
-ENUM_NEXT(eap_type_short_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
-       "RAD",
-       "EXP",
-       "XP");
-ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL);
-
 /*
  * See header
  */
index 4cab845..df354ed 100644 (file)
@@ -23,7 +23,6 @@
 
 typedef struct eap_method_t eap_method_t;
 typedef enum eap_role_t eap_role_t;
-typedef enum eap_type_t eap_type_t;
 typedef enum eap_code_t eap_code_t;
 
 #include <library.h>
@@ -43,35 +42,6 @@ enum eap_role_t {
 extern enum_name_t *eap_role_names;
 
 /**
- * EAP types, defines the EAP method implementation
- */
-enum eap_type_t {
-       EAP_IDENTITY = 1,
-       EAP_NOTIFICATION = 2,
-       EAP_NAK = 3,
-       EAP_MD5 = 4,
-       EAP_OTP = 5,
-       EAP_GTC = 6,
-       EAP_SIM = 18,
-       EAP_AKA = 23,
-       EAP_MSCHAPV2 = 26,
-       /** not a method, but an implementation providing different methods */
-       EAP_RADIUS = 253,
-       EAP_EXPANDED = 254,
-       EAP_EXPERIMENTAL = 255,
-};
-
-/**
- * enum names for eap_type_t.
- */
-extern enum_name_t *eap_type_names;
-
-/**
- * short string enum names for eap_type_t.
- */
-extern enum_name_t *eap_type_short_names;
-
-/**
  * Lookup the EAP method type from a string.
  *
  * @param name         EAP method name (such as "md5", "aka")
index 67197d6..e69f30d 100644 (file)
@@ -63,8 +63,7 @@ static status_t build(private_psk_authenticator_t *this, message_t *message)
        other_id = this->ike_sa->get_other_id(this->ike_sa);
        DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
                 my_id, auth_method_names, AUTH_PSK);
-       key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
-                                                                                 my_id, other_id);
+       key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id, other_id);
        if (key == NULL)
        {
                DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
@@ -107,8 +106,8 @@ static status_t process(private_psk_authenticator_t *this, message_t *message)
        recv_auth_data = auth_payload->get_data(auth_payload);
        my_id = this->ike_sa->get_my_id(this->ike_sa);
        other_id = this->ike_sa->get_other_id(this->ike_sa);
-       enumerator = charon->credentials->create_shared_enumerator(
-                                                       charon->credentials, SHARED_IKE, my_id, other_id);
+       enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
+                                                                                               SHARED_IKE, my_id, other_id);
        while (!authenticated && enumerator->enumerate(enumerator, &key, NULL, NULL))
        {
                keys_found++;
index f1dca27..3c67f6d 100644 (file)
@@ -65,8 +65,7 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message)
 
        id = this->ike_sa->get_my_id(this->ike_sa);
        auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
-       private = charon->credentials->get_private(charon->credentials, KEY_ANY,
-                                                                                          id, auth);
+       private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth);
        if (private == NULL)
        {
                DBG1(DBG_IKE, "no private key found for '%Y'", id);
@@ -178,8 +177,8 @@ static status_t process(private_pubkey_authenticator_t *this, message_t *message
        octets = keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
                                                                         this->nonce, id);
        auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
-       enumerator = charon->credentials->create_public_enumerator(
-                                                                               charon->credentials, key_type, id, auth);
+       enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
+                                                                                                               key_type, id, auth);
        while (enumerator->enumerate(enumerator, &public, &current_auth))
        {
                if (public->verify(public, scheme, octets, auth_data))
index 372405e..34842a5 100644 (file)
@@ -41,7 +41,7 @@ typedef struct ike_sa_t ike_sa_t;
 #include <sa/keymat.h>
 #include <config/peer_cfg.h>
 #include <config/ike_cfg.h>
-#include <config/auth_cfg.h>
+#include <credentials/auth_cfg.h>
 
 /**
  * Timeout in seconds after that a half open IKE_SA gets deleted.
index c831df9..b28739d 100644 (file)
@@ -78,8 +78,7 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
        hasher->destroy(hasher);
        id = identification_create_from_encoding(ID_KEY_ID, hash);
 
-       enumerator = charon->credentials->create_cdp_enumerator(charon->credentials,
-                                                                                                                       CERT_X509, id);
+       enumerator = lib->credmgr->create_cdp_enumerator(lib->credmgr, CERT_X509, id);
        if (enumerator->enumerate(enumerator, &url))
        {
                payload = cert_payload_create_from_hash_and_url(hash, url);
index 0805d02..23412f6 100644 (file)
@@ -93,8 +93,8 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
                                        certificate_t *cert;
 
                                        id = identification_create_from_encoding(ID_KEY_ID, keyid);
-                                       cert = charon->credentials->get_cert(charon->credentials,
-                                                                                       CERT_X509, KEY_ANY, id, TRUE);
+                                       cert = lib->credmgr->get_cert(lib->credmgr,
+                                                                                                 CERT_X509, KEY_ANY, id, TRUE);
                                        if (cert)
                                        {
                                                DBG1(DBG_IKE, "received cert request for \"%Y\"",
@@ -156,8 +156,8 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
                                break;
                        }
                        id = identification_create_from_encoding(ID_KEY_ID, hash);
-                       cert = charon->credentials->get_cert(charon->credentials,
-                                                                                                CERT_X509, KEY_ANY, id, FALSE);
+                       cert = lib->credmgr->get_cert(lib->credmgr,
+                                                                                 CERT_X509, KEY_ANY, id, FALSE);
                        id->destroy(id);
                        break;
                }
@@ -370,8 +370,8 @@ static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
        if (!req)
        {
                /* otherwise add all trusted CA certificates */
-               enumerator = charon->credentials->create_cert_enumerator(
-                                                       charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
+               enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+                                                                                               CERT_ANY, KEY_ANY, NULL, TRUE);
                while (enumerator->enumerate(enumerator, &cert))
                {
                        add_certreq(&req, cert);
index 6bb219a..96d7891 100644 (file)
@@ -39,6 +39,11 @@ credentials/certificates/ocsp_request.h \
 credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
 credentials/certificates/pgp_certificate.h \
 credentials/ietf_attributes/ietf_attributes.c credentials/ietf_attributes/ietf_attributes.h \
+credentials/credential_manager.c credentials/credential_manager.h \
+credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
+credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
+credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
+credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \
 database/database.h database/database_factory.h database/database_factory.c \
 fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
 selectors/traffic_selector.c selectors/traffic_selector.h \
index 157d37b..0b93dc4 100644 (file)
@@ -37,6 +37,11 @@ credentials/certificates/ocsp_request.h \
 credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
 credentials/certificates/pgp_certificate.h \
 credentials/ietf_attributes/ietf_attributes.c credentials/ietf_attributes/ietf_attributes.h \
+credentials/credential_manager.c credentials/credential_manager.h \
+credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
+credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
+credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
+credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \
 database/database.h database/database_factory.h database/database_factory.c \
 fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
 selectors/traffic_selector.c selectors/traffic_selector.h \
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
new file mode 100644 (file)
index 0000000..2573d03
--- /dev/null
@@ -0,0 +1,830 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 "auth_cfg.h"
+
+#include <library.h>
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+#include <credentials/certificates/certificate.h>
+
+ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
+       "any",
+       "public key",
+       "pre-shared key",
+       "EAP",
+);
+
+ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_GTC,
+       "EAP_IDENTITY",
+       "EAP_NOTIFICATION",
+       "EAP_NAK",
+       "EAP_MD5",
+       "EAP_OTP",
+       "EAP_GTC");
+ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_GTC,
+       "EAP_SIM");
+ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
+       "EAP_AKA");
+ENUM_NEXT(eap_type_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
+       "EAP_MSCHAPV2");
+ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
+       "EAP_RADIUS",
+       "EAP_EXPANDED",
+       "EAP_EXPERIMENTAL");
+ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
+
+ENUM_BEGIN(eap_type_short_names, EAP_IDENTITY, EAP_GTC,
+       "ID",
+       "NTF",
+       "NAK",
+       "MD5",
+       "OTP",
+       "GTC");
+ENUM_NEXT(eap_type_short_names, EAP_SIM, EAP_SIM, EAP_GTC,
+       "SIM");
+ENUM_NEXT(eap_type_short_names, EAP_AKA, EAP_AKA, EAP_SIM,
+       "AKA");
+ENUM_NEXT(eap_type_short_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
+       "MSCHAPV2");
+ENUM_NEXT(eap_type_short_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
+       "RAD",
+       "EXP",
+       "XP");
+ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL);
+
+ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
+       "RULE_IDENTITY",
+       "RULE_AUTH_CLASS",
+       "RULE_EAP_IDENTITY",
+       "RULE_EAP_TYPE",
+       "RULE_EAP_VENDOR",
+       "RULE_CA_CERT",
+       "RULE_IM_CERT",
+       "RULE_SUBJECT_CERT",
+       "RULE_CRL_VALIDATION",
+       "RULE_OCSP_VALIDATION",
+       "RULE_GROUP",
+       "HELPER_IM_CERT",
+       "HELPER_SUBJECT_CERT",
+       "HELPER_IM_HASH_URL",
+       "HELPER_SUBJECT_HASH_URL",
+);
+
+typedef struct private_auth_cfg_t private_auth_cfg_t;
+
+/**
+ * private data of item_set
+ */
+struct private_auth_cfg_t {
+
+       /**
+        * public functions
+        */
+       auth_cfg_t public;
+
+       /**
+        * list of entry_t
+        */
+       linked_list_t *entries;
+};
+
+typedef struct entry_t entry_t;
+
+struct entry_t {
+       /** rule type */
+       auth_rule_t type;
+       /** associated value */
+       void *value;
+};
+
+/**
+ * enumerator for auth_cfg_t.create_enumerator()
+ */
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** inner enumerator from linked_list_t */
+       enumerator_t *inner;
+       /** current entry */
+       entry_t *current;
+} entry_enumerator_t;
+
+/**
+ * enumerate function for item_enumerator_t
+ */
+static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
+{
+       entry_t *entry;
+
+       if (this->inner->enumerate(this->inner, &entry))
+       {
+               this->current = entry;
+               *type = entry->type;
+               *value = entry->value;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * destroy function for item_enumerator_t
+ */
+static void entry_enumerator_destroy(entry_enumerator_t *this)
+{
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * Implementation of auth_cfg_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_auth_cfg_t *this)
+{
+       entry_enumerator_t *enumerator;
+
+       enumerator = malloc_thing(entry_enumerator_t);
+       enumerator->inner = this->entries->create_enumerator(this->entries);
+       enumerator->public.enumerate = (void*)enumerate;
+       enumerator->public.destroy = (void*)entry_enumerator_destroy;
+       enumerator->current = NULL;
+       return &enumerator->public;
+}
+
+/**
+ * Destroy the value associated with an entry
+ */
+static void destroy_entry_value(entry_t *entry)
+{
+       switch (entry->type)
+       {
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_GROUP:
+               {
+                       identification_t *id = (identification_t*)entry->value;
+                       id->destroy(id);
+                       break;
+               }
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               {
+                       certificate_t *cert = (certificate_t*)entry->value;
+                       cert->destroy(cert);
+                       break;
+               }
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+               {
+                       free(entry->value);
+                       break;
+               }
+               case AUTH_RULE_AUTH_CLASS:
+               case AUTH_RULE_EAP_TYPE:
+               case AUTH_RULE_EAP_VENDOR:
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       break;
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.replace.
+ */
+static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
+                                       auth_rule_t type, ...)
+{
+       if (enumerator->current)
+       {
+               va_list args;
+
+               va_start(args, type);
+
+               destroy_entry_value(enumerator->current);
+               enumerator->current->type = type;
+               switch (type)
+               {
+                       case AUTH_RULE_AUTH_CLASS:
+                       case AUTH_RULE_EAP_TYPE:
+                       case AUTH_RULE_EAP_VENDOR:
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                               /* integer type */
+                               enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
+                               break;
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       case AUTH_RULE_GROUP:
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       case AUTH_RULE_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                               /* pointer type */
+                               enumerator->current->value = va_arg(args, void*);
+                               break;
+               }
+               va_end(args);
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.get.
+ */
+static void* get(private_auth_cfg_t *this, auth_rule_t type)
+{
+       enumerator_t *enumerator;
+       void *current_value, *best_value = NULL;
+       auth_rule_t current_type;
+       bool found = FALSE;
+
+       enumerator = create_enumerator(this);
+       while (enumerator->enumerate(enumerator, &current_type, &current_value))
+       {
+               if (type == current_type)
+               {
+                       if (type == AUTH_RULE_CRL_VALIDATION ||
+                               type == AUTH_RULE_OCSP_VALIDATION)
+                       {       /* for CRL/OCSP validation, always get() the highest value */
+                               if (!found || current_value > best_value)
+                               {
+                                       best_value = current_value;
+                               }
+                               found = TRUE;
+                               continue;
+                       }
+                       best_value = current_value;
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       if (found)
+       {
+               return best_value;
+       }
+       switch (type)
+       {
+               /* use some sane defaults if we don't find an entry */
+               case AUTH_RULE_AUTH_CLASS:
+                       return (void*)AUTH_CLASS_ANY;
+               case AUTH_RULE_EAP_TYPE:
+                       return (void*)EAP_NAK;
+               case AUTH_RULE_EAP_VENDOR:
+                       return (void*)0;
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       return (void*)VALIDATION_FAILED;
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_GROUP:
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+               default:
+                       return NULL;
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.add.
+ */
+static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
+{
+       entry_t *entry = malloc_thing(entry_t);
+       va_list args;
+
+       va_start(args, type);
+       entry->type = type;
+       switch (type)
+       {
+               case AUTH_RULE_AUTH_CLASS:
+               case AUTH_RULE_EAP_TYPE:
+               case AUTH_RULE_EAP_VENDOR:
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       /* integer type */
+                       entry->value = (void*)(uintptr_t)va_arg(args, u_int);
+                       break;
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_GROUP:
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+                       /* pointer type */
+                       entry->value = va_arg(args, void*);
+                       break;
+       }
+       va_end(args);
+       this->entries->insert_last(this->entries, entry);
+}
+
+/**
+ * Implementation of auth_cfg_t.complies.
+ */
+static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
+                                        bool log_error)
+{
+       enumerator_t *e1, *e2;
+       bool success = TRUE, has_group = FALSE, group_match = FALSE;
+       auth_rule_t t1, t2;
+       void *value;
+
+       e1 = constraints->create_enumerator(constraints);
+       while (e1->enumerate(e1, &t1, &value))
+       {
+               switch (t1)
+               {
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       {
+                               certificate_t *c1, *c2;
+
+                               c1 = (certificate_t*)value;
+
+                               success = FALSE;
+                               e2 = create_enumerator(this);
+                               while (e2->enumerate(e2, &t2, &c2))
+                               {
+                                       if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
+                                               c1->equals(c1, c2))
+                                       {
+                                               success = TRUE;
+                                       }
+                               }
+                               e2->destroy(e2);
+                               if (!success && log_error)
+                               {
+                                       DBG1(DBG_CFG, "constraint check failed: peer not "
+                                                "authenticated by CA '%Y'.", c1->get_subject(c1));
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_SUBJECT_CERT:
+                       {
+                               certificate_t *c1, *c2;
+
+                               c1 = (certificate_t*)value;
+                               c2 = get(this, AUTH_RULE_SUBJECT_CERT);
+                               if (!c2 || !c1->equals(c1, c2))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint check failed: peer not "
+                                                        "authenticated with peer cert '%Y'.",
+                                                        c1->get_subject(c1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                       {
+                               cert_validation_t validated, required;
+
+                               required = (uintptr_t)value;
+                               validated = (uintptr_t)get(this, t1);
+                               switch (required)
+                               {
+                                       case VALIDATION_FAILED:
+                                               /* no constraint */
+                                               break;
+                                       case VALIDATION_SKIPPED:
+                                               if (validated == VALIDATION_SKIPPED)
+                                               {
+                                                       break;
+                                               }
+                                               /* FALL */
+                                       case VALIDATION_GOOD:
+                                               if (validated == VALIDATION_GOOD)
+                                               {
+                                                       break;
+                                               }
+                                               /* FALL */
+                                       default:
+                                               success = FALSE;
+                                               if (log_error)
+                                               {
+                                                       DBG1(DBG_CFG, "constraint check failed: %N is %N, "
+                                                                "but requires at least %N", auth_rule_names,
+                                                                t1, cert_validation_names, validated,
+                                                                cert_validation_names, required);
+                                               }
+                                               break;
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       {
+                               identification_t *id1, *id2;
+
+                               id1 = (identification_t*)value;
+                               id2 = get(this, t1);
+                               if (!id2 || !id2->matches(id2, id1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
+                                                        " required ", t1 == AUTH_RULE_IDENTITY ? "" :
+                                                        "EAP ", id1);
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_AUTH_CLASS:
+                       {
+                               if ((uintptr_t)value != AUTH_CLASS_ANY &&
+                                       (uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires %N authentication, "
+                                                        "but %N was used", auth_class_names, (uintptr_t)value,
+                                                        auth_class_names, (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_EAP_TYPE:
+                       {
+                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires %N, "
+                                                        "but %N was used", eap_type_names, (uintptr_t)value,
+                                                        eap_type_names,  (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_EAP_VENDOR:
+                       {
+                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
+                                                        "but %d was used", (uintptr_t)value,
+                                                        (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_GROUP:
+                       {
+                               identification_t *id1, *id2;
+
+                               /* for groups, a match of a single group is sufficient */
+                               has_group = TRUE;
+                               id1 = (identification_t*)value;
+                               e2 = create_enumerator(this);
+                               while (e2->enumerate(e2, &t2, &id2))
+                               {
+                                       if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1))
+                                       {
+                                               group_match = TRUE;
+                                       }
+                               }
+                               e2->destroy(e2);
+                               break;
+                       }
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                               /* skip helpers */
+                               continue;
+               }
+               if (!success)
+               {
+                       break;
+               }
+       }
+       e1->destroy(e1);
+
+       if (has_group && !group_match)
+       {
+               if (log_error)
+               {
+                       DBG1(DBG_CFG, "constraint check failed: group membership required");
+               }
+               return FALSE;
+       }
+       return success;
+}
+
+/**
+ * Implementation of auth_cfg_t.merge.
+ */
+static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
+{
+       if (!other)
+       {       /* nothing to merge */
+               return;
+       }
+       if (copy)
+       {
+               enumerator_t *enumerator;
+               auth_rule_t type;
+               void *value;
+
+               enumerator = create_enumerator(other);
+               while (enumerator->enumerate(enumerator, &type, &value))
+               {
+                       switch (type)
+                       {
+                               case AUTH_RULE_CA_CERT:
+                               case AUTH_RULE_IM_CERT:
+                               case AUTH_RULE_SUBJECT_CERT:
+                               case AUTH_HELPER_IM_CERT:
+                               case AUTH_HELPER_SUBJECT_CERT:
+                               {
+                                       certificate_t *cert = (certificate_t*)value;
+
+                                       add(this, type, cert->get_ref(cert));
+                                       break;
+                               }
+                               case AUTH_RULE_CRL_VALIDATION:
+                               case AUTH_RULE_OCSP_VALIDATION:
+                               case AUTH_RULE_AUTH_CLASS:
+                               case AUTH_RULE_EAP_TYPE:
+                               case AUTH_RULE_EAP_VENDOR:
+                               {
+                                       add(this, type, (uintptr_t)value);
+                                       break;
+                               }
+                               case AUTH_RULE_IDENTITY:
+                               case AUTH_RULE_EAP_IDENTITY:
+                               case AUTH_RULE_GROUP:
+                               {
+                                       identification_t *id = (identification_t*)value;
+
+                                       add(this, type, id->clone(id));
+                                       break;
+                               }
+                               case AUTH_HELPER_IM_HASH_URL:
+                               case AUTH_HELPER_SUBJECT_HASH_URL:
+                               {
+                                       add(this, type, strdup((char*)value));
+                                       break;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       else
+       {
+               entry_t *entry;
+
+               while (other->entries->remove_first(other->entries,
+                                                                                       (void**)&entry) == SUCCESS)
+               {
+                       this->entries->insert_last(this->entries, entry);
+               }
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.equals.
+ */
+static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
+{
+       enumerator_t *e1, *e2;
+       entry_t *i1, *i2;
+       bool equal = TRUE, found;
+
+       if (this->entries->get_count(this->entries) !=
+               other->entries->get_count(other->entries))
+       {
+               return FALSE;
+       }
+       e1 = this->entries->create_enumerator(this->entries);
+       while (e1->enumerate(e1, &i1))
+       {
+               found = FALSE;
+               e2 = other->entries->create_enumerator(other->entries);
+               while (e2->enumerate(e2, &i2))
+               {
+                       if (i1->type == i2->type)
+                       {
+                               switch (i1->type)
+                               {
+                                       case AUTH_RULE_AUTH_CLASS:
+                                       case AUTH_RULE_EAP_TYPE:
+                                       case AUTH_RULE_EAP_VENDOR:
+                                       case AUTH_RULE_CRL_VALIDATION:
+                                       case AUTH_RULE_OCSP_VALIDATION:
+                                       {
+                                               if (i1->value == i2->value)
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_RULE_CA_CERT:
+                                       case AUTH_RULE_IM_CERT:
+                                       case AUTH_RULE_SUBJECT_CERT:
+                                       case AUTH_HELPER_IM_CERT:
+                                       case AUTH_HELPER_SUBJECT_CERT:
+                                       {
+                                               certificate_t *c1, *c2;
+
+                                               c1 = (certificate_t*)i1->value;
+                                               c2 = (certificate_t*)i2->value;
+
+                                               if (c1->equals(c1, c2))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_RULE_IDENTITY:
+                                       case AUTH_RULE_EAP_IDENTITY:
+                                       case AUTH_RULE_GROUP:
+                                       {
+                                               identification_t *id1, *id2;
+
+                                               id1 = (identification_t*)i1->value;
+                                               id2 = (identification_t*)i2->value;
+
+                                               if (id1->equals(id1, id2))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_HELPER_IM_HASH_URL:
+                                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                                       {
+                                               if (streq(i1->value, i2->value))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                               }
+                               break;
+                       }
+               }
+               e2->destroy(e2);
+               if (!found)
+               {
+                       equal = FALSE;
+                       break;
+               }
+       }
+       e1->destroy(e1);
+       return equal;
+}
+
+/**
+ * Implementation of auth_cfg_t.purge
+ */
+static void purge(private_auth_cfg_t *this, bool keep_ca)
+{
+       entry_t *entry;
+       linked_list_t *cas;
+
+       cas = linked_list_create();
+       while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
+       {
+               if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
+               {
+                       cas->insert_first(cas, entry);
+               }
+               else
+               {
+                       destroy_entry_value(entry);
+                       free(entry);
+               }
+       }
+       while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
+       {
+               this->entries->insert_first(this->entries, entry);
+       }
+       cas->destroy(cas);
+}
+
+/**
+ * Implementation of auth_cfg_t.clone
+ */
+static auth_cfg_t* clone_(private_auth_cfg_t *this)
+{
+       enumerator_t *enumerator;
+       auth_cfg_t *clone;
+       entry_t *entry;
+
+       clone = auth_cfg_create();
+       enumerator = this->entries->create_enumerator(this->entries);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               switch (entry->type)
+               {
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       case AUTH_RULE_GROUP:
+                       {
+                               identification_t *id = (identification_t*)entry->value;
+                               clone->add(clone, entry->type, id->clone(id));
+                               break;
+                       }
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       case AUTH_RULE_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       {
+                               certificate_t *cert = (certificate_t*)entry->value;
+                               clone->add(clone, entry->type, cert->get_ref(cert));
+                               break;
+                       }
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                       {
+                               clone->add(clone, entry->type, strdup(entry->value));
+                               break;
+                       }
+                       case AUTH_RULE_AUTH_CLASS:
+                       case AUTH_RULE_EAP_TYPE:
+                       case AUTH_RULE_EAP_VENDOR:
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                               clone->add(clone, entry->type, (uintptr_t)entry->value);
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return clone;
+}
+
+/**
+ * Implementation of auth_cfg_t.destroy
+ */
+static void destroy(private_auth_cfg_t *this)
+{
+       purge(this, FALSE);
+       this->entries->destroy(this->entries);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+auth_cfg_t *auth_cfg_create()
+{
+       private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
+
+       this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
+       this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
+       this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
+       this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
+       this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
+       this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
+       this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
+       this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
+       this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
+       this->public.destroy = (void(*)(auth_cfg_t*))destroy;
+
+       this->entries = linked_list_create();
+
+       return &this->public;
+}
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
new file mode 100644 (file)
index 0000000..713e163
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 auth_cfg auth_cfg
+ * @{ @ingroup credentials
+ */
+
+#ifndef AUTH_CFG_H_
+#define AUTH_CFG_H_
+
+#include <utils/enumerator.h>
+
+typedef struct auth_cfg_t auth_cfg_t;
+typedef enum auth_rule_t auth_rule_t;
+typedef enum auth_class_t auth_class_t;
+typedef enum eap_type_t eap_type_t;
+
+/**
+ * Class of authentication to use. This is different to auth_method_t in that
+ * it does not specify a method, but a class of acceptable methods. The found
+ * certificate finally dictates wich method is used.
+ */
+enum auth_class_t {
+       /** any class acceptable */
+       AUTH_CLASS_ANY = 0,
+       /** authentication using public keys (RSA, ECDSA) */
+       AUTH_CLASS_PUBKEY = 1,
+       /** authentication using a pre-shared secrets */
+       AUTH_CLASS_PSK = 2,
+       /** authentication using EAP */
+       AUTH_CLASS_EAP = 3,
+};
+
+/**
+ * enum strings for auth_class_t
+ */
+extern enum_name_t *auth_class_names;
+
+/**
+ * EAP types, defines the EAP method implementation
+ */
+enum eap_type_t {
+       EAP_IDENTITY = 1,
+       EAP_NOTIFICATION = 2,
+       EAP_NAK = 3,
+       EAP_MD5 = 4,
+       EAP_OTP = 5,
+       EAP_GTC = 6,
+       EAP_SIM = 18,
+       EAP_AKA = 23,
+       EAP_MSCHAPV2 = 26,
+       /** not a method, but an implementation providing different methods */
+       EAP_RADIUS = 253,
+       EAP_EXPANDED = 254,
+       EAP_EXPERIMENTAL = 255,
+};
+
+/**
+ * enum names for eap_type_t.
+ */
+extern enum_name_t *eap_type_names;
+
+/**
+ * short string enum names for eap_type_t.
+ */
+extern enum_name_t *eap_type_short_names;
+
+/**
+ * Authentication config to use during authentication process.
+ *
+ * Each authentication config contains a set of rules. These rule-sets are used
+ * in two ways:
+ * - For configs specifying local authentication behavior, the rules define
+ *   which authentication method in which way.
+ * - For configs specifying remote peer authentication, the rules define
+ *   constraints the peer has to fullfill.
+ *
+ * Additionally to the rules, there is a set of helper items. These are used
+ * to transport credentials during the authentication process.
+ */
+enum auth_rule_t {
+
+       /** identity to use for IKEv2 authentication exchange, identification_t* */
+       AUTH_RULE_IDENTITY,
+       /** authentication class, auth_class_t */
+       AUTH_RULE_AUTH_CLASS,
+       /** EAP identity to use within EAP-Identity exchange, identification_t* */
+       AUTH_RULE_EAP_IDENTITY,
+       /** EAP type to propose for peer authentication, eap_type_t */
+       AUTH_RULE_EAP_TYPE,
+       /** EAP vendor for vendor specific type, u_int32_t */
+       AUTH_RULE_EAP_VENDOR,
+       /** certificate authority, certificate_t* */
+       AUTH_RULE_CA_CERT,
+       /** intermediate certificate in trustchain, certificate_t* */
+       AUTH_RULE_IM_CERT,
+       /** subject certificate, certificate_t* */
+       AUTH_RULE_SUBJECT_CERT,
+       /** result of a CRL validation, cert_validation_t */
+       AUTH_RULE_CRL_VALIDATION,
+       /** result of a OCSP validation, cert_validation_t */
+       AUTH_RULE_OCSP_VALIDATION,
+       /** subject is member of a group, identification_t*
+        * The group membership constraint is fulfilled if the subject is member of
+        * one group defined in the constraints. */
+       AUTH_RULE_GROUP,
+
+       /** intermediate certificate, certificate_t* */
+       AUTH_HELPER_IM_CERT,
+       /** subject certificate, certificate_t* */
+       AUTH_HELPER_SUBJECT_CERT,
+       /** Hash and URL of a intermediate certificate, char* */
+       AUTH_HELPER_IM_HASH_URL,
+       /** Hash and URL of a end-entity certificate, char* */
+       AUTH_HELPER_SUBJECT_HASH_URL,
+};
+
+/**
+ * enum name for auth_rule_t.
+ */
+extern enum_name_t *auth_rule_names;
+
+/**
+ * Authentication/Authorization round.
+ *
+ * RFC4739 defines multiple authentication rounds. This class defines such
+ * a round from a configuration perspective, either for the local or the remote
+ * peer. Local config are called "rulesets", as they define how we authenticate.
+ * Remote peer configs are called "constraits", they define what is needed to
+ * complete the authentication round successfully.
+ *
+ * @verbatim
+
+   [Repeat for each configuration]
+   +--------------------------------------------------+
+   |                                                  |
+   |                                                  |
+   |   +----------+     IKE_AUTH       +--------- +   |
+   |   |  config  |   ----------->     |          |   |
+   |   |  ruleset |                    |          |   |
+   |   +----------+ [ <----------- ]   |          |   |
+   |                [ optional EAP ]   |   Peer   |   |
+   |   +----------+ [ -----------> ]   |          |   |
+   |   |  config  |                    |          |   |
+   |   |  constr. |   <-----------     |          |   |
+   |   +----------+     IKE_AUTH       +--------- +   |
+   |                                                  |
+   |                                                  |
+   +--------------------------------------------------+
+
+   @endverbatim
+ *
+ * Values for each items are either pointers (casted to void*) or short
+ * integers (use uintptr_t cast).
+ */
+struct auth_cfg_t {
+
+       /**
+        * Add an rule to the set.
+        *
+        * @param rule          rule type
+        * @param ...           associated value to rule
+        */
+       void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
+
+       /**
+        * Get an rule value.
+        *
+        * @param rule          rule type
+        * @return                      bool if item has been found
+        */
+       void* (*get)(auth_cfg_t *this, auth_rule_t rule);
+
+       /**
+        * Create an enumerator over added rules.
+        *
+        * @return                      enumerator over (auth_rule_t, union{void*,uintpr_t})
+        */
+       enumerator_t* (*create_enumerator)(auth_cfg_t *this);
+
+       /**
+        * Replace an rule at enumerator position.
+        *
+        * @param pos           enumerator position position
+        * @param rule          rule type
+        * @param ...           associated value to rule
+        */
+       void (*replace)(auth_cfg_t *this, enumerator_t *pos,
+                                       auth_rule_t rule, ...);
+
+       /**
+        * Check if a used config fulfills a set of configured constraints.
+        *
+        * @param constraints   required authorization rules
+        * @param log_error             wheter to log compliance errors
+        * @return                              TRUE if this complies with constraints
+        */
+       bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error);
+
+       /**
+        * Merge items from other into this.
+        *
+        * @param other         items to read for merge
+        * @param copy          TRUE to copy items, FALSE to move them
+        */
+       void (*merge)(auth_cfg_t *this, auth_cfg_t *other, bool copy);
+
+       /**
+        * Purge all rules in a config.
+        *
+        * @param keep_ca       wheter to keep AUTH_RULE_CA_CERT entries
+        */
+       void (*purge)(auth_cfg_t *this, bool keep_ca);
+
+       /**
+        * Check two configs for equality.
+        *
+        * @param other         other config to compaire against this
+        * @return                      TRUE if auth infos identical
+        */
+       bool (*equals)(auth_cfg_t *this, auth_cfg_t *other);
+
+       /**
+        * Clone a authentication config, including all rules.
+        *
+        * @return                      cloned configuration
+        */
+       auth_cfg_t* (*clone)(auth_cfg_t *this);
+
+       /**
+        * Destroy a config with all associated rules/values.
+        */
+       void (*destroy)(auth_cfg_t *this);
+};
+
+/**
+ * Create a authentication config.
+ */
+auth_cfg_t *auth_cfg_create();
+
+#endif /** AUTH_CFG_H_ @}*/
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
new file mode 100644 (file)
index 0000000..73f42af
--- /dev/null
@@ -0,0 +1,1679 @@
+/*
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 "credential_manager.h"
+
+#include <library.h>
+#include <debug.h>
+#include <threading/thread_value.h>
+#include <threading/mutex.h>
+#include <threading/rwlock.h>
+#include <selectors/traffic_selector.h>
+#include <utils/linked_list.h>
+#include <credentials/sets/cert_cache.h>
+#include <credentials/sets/auth_cfg_wrapper.h>
+#include <credentials/sets/ocsp_response_wrapper.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/certificates/crl.h>
+#include <credentials/certificates/ocsp_request.h>
+#include <credentials/certificates/ocsp_response.h>
+
+/**
+ * Maximum length of a certificate trust chain
+ */
+#define MAX_TRUST_PATH_LEN 7
+
+typedef struct private_credential_manager_t private_credential_manager_t;
+
+/**
+ * private data of credential_manager
+ */
+struct private_credential_manager_t {
+
+       /**
+        * public functions
+        */
+       credential_manager_t public;
+
+       /**
+        * list of credential sets
+        */
+       linked_list_t *sets;
+
+       /**
+        * thread local set of credentials, linked_list_t with credential_set_t's
+        */
+       thread_value_t *local_sets;
+
+       /**
+        * trust relationship and certificate cache
+        */
+       cert_cache_t *cache;
+
+       /**
+        * certificates queued for persistent caching
+        */
+       linked_list_t *cache_queue;
+
+       /**
+        * read-write lock to sets list
+        */
+       rwlock_t *lock;
+
+       /**
+        * mutex for cache queue
+        */
+       mutex_t *queue_mutex;
+};
+
+/** data to pass to create_private_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       key_type_t type;
+       identification_t* keyid;
+} private_data_t;
+
+/** data to pass to create_cert_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       certificate_type_t cert;
+       key_type_t key;
+       identification_t *id;
+       bool trusted;
+} cert_data_t;
+
+/** data to pass to create_cdp_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       certificate_type_t type;
+       identification_t *id;
+} cdp_data_t;
+
+/** data to pass to create_shared_enumerator */
+typedef struct {
+       private_credential_manager_t *this;
+       shared_key_type_t type;
+       identification_t *me;
+       identification_t *other;
+} shared_data_t;
+
+/** enumerator over local and global sets */
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** enumerator over global sets */
+       enumerator_t *global;
+       /** enumerator over local sets */
+       enumerator_t *local;
+} sets_enumerator_t;
+
+/**
+ * destroy a sets_enumerator_t
+ */
+static void sets_enumerator_destroy(sets_enumerator_t *this)
+{
+       DESTROY_IF(this->global);
+       DESTROY_IF(this->local);
+       free(this);
+}
+
+/**
+ * sets_enumerator_t.enumerate
+ */
+static bool sets_enumerator_enumerate(sets_enumerator_t *this,
+                                                                         credential_set_t **set)
+{
+       if (this->global)
+       {
+               if (this->global->enumerate(this->global, set))
+               {
+                       return TRUE;
+               }
+               /* end of global sets, look for local */
+               this->global->destroy(this->global);
+               this->global = NULL;
+       }
+       if (this->local)
+       {
+               return this->local->enumerate(this->local, set);
+       }
+       return FALSE;
+}
+
+/**
+ * create an enumerator over both, global and local sets
+ */
+static enumerator_t *create_sets_enumerator(private_credential_manager_t *this)
+{
+       linked_list_t *local;
+       sets_enumerator_t *enumerator = malloc_thing(sets_enumerator_t);
+
+       enumerator->public.enumerate = (void*)sets_enumerator_enumerate;
+       enumerator->public.destroy = (void*)sets_enumerator_destroy;
+       enumerator->global = this->sets->create_enumerator(this->sets);
+       enumerator->local = NULL;
+       local = this->local_sets->get(this->local_sets);
+       if (local)
+       {
+               enumerator->local = local->create_enumerator(local);
+       }
+       return &enumerator->public;
+}
+
+/**
+ * cleanup function for cert data
+ */
+static void destroy_cert_data(cert_data_t *data)
+{
+       data->this->lock->unlock(data->this->lock);
+       free(data);
+}
+
+/**
+ * enumerator constructor for certificates
+ */
+static enumerator_t *create_cert(credential_set_t *set, cert_data_t *data)
+{
+       return set->create_cert_enumerator(set, data->cert, data->key,
+                                                                          data->id, data->trusted);
+}
+
+/**
+ * Implementation of credential_manager_t.create_cert_enumerator.
+ */
+static enumerator_t *create_cert_enumerator(private_credential_manager_t *this,
+                                               certificate_type_t certificate, key_type_t key,
+                                               identification_t *id, bool trusted)
+{
+       cert_data_t *data = malloc_thing(cert_data_t);
+       data->this = this;
+       data->cert = certificate;
+       data->key = key;
+       data->id = id;
+       data->trusted = trusted;
+
+       this->lock->read_lock(this->lock);
+       return enumerator_create_nested(create_sets_enumerator(this),
+                                                                       (void*)create_cert, data,
+                                                                       (void*)destroy_cert_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_cert.
+ */
+static certificate_t *get_cert(private_credential_manager_t *this,
+                                               certificate_type_t cert, key_type_t key,
+                                               identification_t *id, bool trusted)
+{
+       certificate_t *current, *found = NULL;
+       enumerator_t *enumerator;
+
+       enumerator = create_cert_enumerator(this, cert, key, id, trusted);
+       if (enumerator->enumerate(enumerator, &current))
+       {
+               /* TODO: best match? order by keyid, subject, sualtname */
+               found = current->get_ref(current);
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+
+/**
+ * cleanup function for cdp data
+ */
+static void destroy_cdp_data(cdp_data_t *data)
+{
+       data->this->lock->unlock(data->this->lock);
+       free(data);
+}
+
+/**
+ * enumerator constructor for CDPs
+ */
+static enumerator_t *create_cdp(credential_set_t *set, cdp_data_t *data)
+{
+       return set->create_cdp_enumerator(set, data->type, data->id);
+}
+/**
+ * Implementation of credential_manager_t.create_cdp_enumerator.
+ */
+static enumerator_t * create_cdp_enumerator(private_credential_manager_t *this,
+                                                               certificate_type_t type, identification_t *id)
+{
+       cdp_data_t *data = malloc_thing(cdp_data_t);
+       data->this = this;
+       data->type = type;
+       data->id = id;
+
+       this->lock->read_lock(this->lock);
+       return enumerator_create_nested(create_sets_enumerator(this),
+                                                                       (void*)create_cdp, data,
+                                                                       (void*)destroy_cdp_data);
+}
+
+/**
+ * cleanup function for private data
+ */
+static void destroy_private_data(private_data_t *data)
+{
+       data->this->lock->unlock(data->this->lock);
+       free(data);
+}
+
+/**
+ * enumerator constructor for private keys
+ */
+static enumerator_t *create_private(credential_set_t *set, private_data_t *data)
+{
+       return set->create_private_enumerator(set, data->type, data->keyid);
+}
+
+/**
+ * Implementation of credential_manager_t.create_private_enumerator.
+ */
+static enumerator_t* create_private_enumerator(
+                                                                       private_credential_manager_t *this,
+                                                                       key_type_t key, identification_t *keyid)
+{
+       private_data_t *data;
+
+       data = malloc_thing(private_data_t);
+       data->this = this;
+       data->type = key;
+       data->keyid = keyid;
+       this->lock->read_lock(this->lock);
+       return enumerator_create_nested(create_sets_enumerator(this),
+                                                                       (void*)create_private, data,
+                                                                       (void*)destroy_private_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_private_by_keyid.
+ */
+static private_key_t *get_private_by_keyid(private_credential_manager_t *this,
+                                                                               key_type_t key, identification_t *keyid)
+{
+       private_key_t *found = NULL;
+       enumerator_t *enumerator;
+
+       enumerator = create_private_enumerator(this, key, keyid);
+       if (enumerator->enumerate(enumerator, &found))
+       {
+               found->get_ref(found);
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * cleanup function for shared data
+ */
+static void destroy_shared_data(shared_data_t *data)
+{
+       data->this->lock->unlock(data->this->lock);
+       free(data);
+}
+
+/**
+ * enumerator constructor for shared keys
+ */
+static enumerator_t *create_shared(credential_set_t *set, shared_data_t *data)
+{
+       return set->create_shared_enumerator(set, data->type, data->me, data->other);
+}
+
+/**
+ * Implementation of credential_manager_t.create_shared_enumerator.
+ */
+static enumerator_t *create_shared_enumerator(private_credential_manager_t *this,
+                                               shared_key_type_t type,
+                                               identification_t *me, identification_t *other)
+{
+       shared_data_t *data = malloc_thing(shared_data_t);
+       data->this = this;
+       data->type = type;
+       data->me = me;
+       data->other = other;
+
+       this->lock->read_lock(this->lock);
+       return enumerator_create_nested(create_sets_enumerator(this),
+                                                                       (void*)create_shared, data,
+                                                                       (void*)destroy_shared_data);
+}
+
+/**
+ * Implementation of credential_manager_t.get_shared.
+ */
+static shared_key_t *get_shared(private_credential_manager_t *this,
+                                                               shared_key_type_t type, identification_t *me,
+                                                               identification_t *other)
+{
+       shared_key_t *current, *found = NULL;
+       id_match_t *best_me = ID_MATCH_NONE, *best_other = ID_MATCH_NONE;
+       id_match_t *match_me, *match_other;
+       enumerator_t *enumerator;
+
+       enumerator = create_shared_enumerator(this, type, me, other);
+       while (enumerator->enumerate(enumerator, &current, &match_me, &match_other))
+       {
+               if (match_other > best_other ||
+                       (match_other == best_other && match_me > best_me))
+               {
+                       DESTROY_IF(found);
+                       found = current->get_ref(current);
+                       best_me = match_me;
+                       best_other = match_other;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return found;
+}
+
+/**
+ * add a credential set to the thread local list
+ */
+static void add_local_set(private_credential_manager_t *this,
+                                                 credential_set_t *set)
+{
+       linked_list_t *sets;
+
+       sets = this->local_sets->get(this->local_sets);
+       if (!sets)
+       {       /* first invocation */
+               sets = linked_list_create();
+               this->local_sets->set(this->local_sets, sets);
+       }
+       sets->insert_last(sets, set);
+}
+
+/**
+ * remove a credential set from the thread local list
+ */
+static void remove_local_set(private_credential_manager_t *this,
+                                                        credential_set_t *set)
+{
+       linked_list_t *sets;
+
+       sets = this->local_sets->get(this->local_sets);
+       sets->remove(sets, set, NULL);
+}
+
+/**
+ * Implementation of credential_manager_t.cache_cert.
+ */
+static void cache_cert(private_credential_manager_t *this, certificate_t *cert)
+{
+       credential_set_t *set;
+       enumerator_t *enumerator;
+
+       if (this->lock->try_write_lock(this->lock))
+       {
+               enumerator = this->sets->create_enumerator(this->sets);
+               while (enumerator->enumerate(enumerator, &set))
+               {
+                       set->cache_cert(set, cert);
+               }
+               enumerator->destroy(enumerator);
+               this->lock->unlock(this->lock);
+       }
+       else
+       {       /* we can't cache now as other threads are active, queue for later */
+               this->queue_mutex->lock(this->queue_mutex);
+               this->cache_queue->insert_last(this->cache_queue, cert->get_ref(cert));
+               this->queue_mutex->unlock(this->queue_mutex);
+       }
+}
+
+/**
+ * Try to cache certificates queued for caching
+ */
+static void cache_queue(private_credential_manager_t *this)
+{
+       credential_set_t *set;
+       certificate_t *cert;
+       enumerator_t *enumerator;
+
+       this->queue_mutex->lock(this->queue_mutex);
+       if (this->cache_queue->get_count(this->cache_queue) > 0 &&
+               this->lock->try_write_lock(this->lock))
+       {
+               while (this->cache_queue->remove_last(this->cache_queue,
+                                                                                         (void**)&cert) == SUCCESS)
+               {
+                       enumerator = this->sets->create_enumerator(this->sets);
+                       while (enumerator->enumerate(enumerator, &set))
+                       {
+                               set->cache_cert(set, cert);
+                       }
+                       enumerator->destroy(enumerator);
+                       cert->destroy(cert);
+               }
+               this->lock->unlock(this->lock);
+       }
+       this->queue_mutex->unlock(this->queue_mutex);
+}
+
+/**
+ * forward declaration
+ */
+static enumerator_t *create_trusted_enumerator(private_credential_manager_t *this,
+                                       key_type_t type, identification_t *id, bool online);
+
+/**
+ * Do an OCSP request
+ */
+static certificate_t *fetch_ocsp(private_credential_manager_t *this, char *url,
+                                                                certificate_t *subject, certificate_t *issuer)
+{
+       certificate_t *request, *response;
+       chunk_t send, receive;
+
+       /* TODO: requestor name, signature */
+       request = lib->creds->create(lib->creds,
+                                               CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST,
+                                               BUILD_CA_CERT, issuer,
+                                               BUILD_CERT, subject, BUILD_END);
+       if (!request)
+       {
+               DBG1(DBG_CFG, "generating ocsp request failed");
+               return NULL;
+       }
+
+       send = request->get_encoding(request);
+       request->destroy(request);
+
+       DBG1(DBG_CFG, "  requesting ocsp status from '%s' ...", url);
+       if (lib->fetcher->fetch(lib->fetcher, url, &receive,
+                                                       FETCH_REQUEST_DATA, send,
+                                                       FETCH_REQUEST_TYPE, "application/ocsp-request",
+                                                       FETCH_END) != SUCCESS)
+       {
+               DBG1(DBG_CFG, "ocsp request to %s failed", url);
+               chunk_free(&send);
+               return NULL;
+       }
+       chunk_free(&send);
+
+       response = lib->creds->create(lib->creds,
+                                                                 CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE,
+                                                                 BUILD_BLOB_ASN1_DER, receive, BUILD_END);
+       chunk_free(&receive);
+       if (!response)
+       {
+               DBG1(DBG_CFG, "parsing ocsp response failed");
+               return NULL;
+       }
+       return response;
+}
+
+/**
+ * check the signature of an OCSP response
+ */
+static bool verify_ocsp(private_credential_manager_t *this,
+                                               ocsp_response_t *response)
+{
+       certificate_t *issuer, *subject;
+       identification_t *responder;
+       ocsp_response_wrapper_t *wrapper;
+       enumerator_t *enumerator;
+       bool verified = FALSE;
+
+       wrapper = ocsp_response_wrapper_create((ocsp_response_t*)response);
+       add_local_set(this, &wrapper->set);
+
+       subject = &response->certificate;
+       responder = subject->get_issuer(subject);
+       enumerator = create_trusted_enumerator(this, KEY_ANY, responder, FALSE);
+       while (enumerator->enumerate(enumerator, &issuer, NULL))
+       {
+               if (this->cache->issued_by(this->cache, subject, issuer))
+               {
+                       DBG1(DBG_CFG, "  ocsp response correctly signed by \"%Y\"",
+                                                        issuer->get_subject(issuer));
+                       verified = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       remove_local_set(this, &wrapper->set);
+       wrapper->destroy(wrapper);
+       return verified;
+}
+
+/**
+ * Get the better of two OCSP responses, and check for usable OCSP info
+ */
+static certificate_t *get_better_ocsp(private_credential_manager_t *this,
+                                                                         certificate_t *cand, certificate_t *best,
+                                                                         x509_t *subject, x509_t *issuer,
+                                                                         cert_validation_t *valid, bool cache)
+{
+       ocsp_response_t *response;
+       time_t revocation, this_update, next_update, valid_until;
+       crl_reason_t reason;
+       bool revoked = FALSE;
+
+       response = (ocsp_response_t*)cand;
+
+       /* check ocsp signature */
+       if (!verify_ocsp(this, response))
+       {
+               DBG1(DBG_CFG, "ocsp response verification failed");
+               cand->destroy(cand);
+               return best;
+       }
+       /* check if response contains our certificate */
+       switch (response->get_status(response, subject, issuer, &revocation, &reason,
+                                                                &this_update, &next_update))
+       {
+               case VALIDATION_REVOKED:
+                       /* subject has been revoked by a valid OCSP response */
+                       DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
+                                                 &revocation, TRUE, crl_reason_names, reason);
+                       revoked = TRUE;
+                       break;
+               case VALIDATION_GOOD:
+                       /* results in either good or stale */
+                       break;
+               default:
+               case VALIDATION_FAILED:
+                       /* candidate unusable, does not contain our cert */
+                       DBG1(DBG_CFG, "  ocsp response contains no status on our certificate");
+                       cand->destroy(cand);
+                       return best;
+       }
+
+       /* select the better of the two responses */
+       if (best == NULL || certificate_is_newer(cand, best))
+       {
+               DESTROY_IF(best);
+               best = cand;
+               if (best->get_validity(best, NULL, NULL, &valid_until))
+               {
+                       DBG1(DBG_CFG, "  ocsp response is valid: until %T",
+                                                        &valid_until, FALSE);
+                       *valid = VALIDATION_GOOD;
+                       if (cache)
+                       {       /* cache non-stale only, stale certs get refetched */
+                               cache_cert(this, best);
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "  ocsp response is stale: since %T",
+                                                        &valid_until, FALSE);
+                       *valid = VALIDATION_STALE;
+               }
+       }
+       else
+       {
+               *valid = VALIDATION_STALE;
+               cand->destroy(cand);
+       }
+       if (revoked)
+       {       /* revoked always counts, even if stale */
+               *valid = VALIDATION_REVOKED;
+       }
+       return best;
+}
+
+/**
+ * validate a x509 certificate using OCSP
+ */
+static cert_validation_t check_ocsp(private_credential_manager_t *this,
+                                                                       x509_t *subject, x509_t *issuer,
+                                                                       auth_cfg_t *auth)
+{
+       enumerator_t *enumerator;
+       cert_validation_t valid = VALIDATION_SKIPPED;
+       certificate_t *best = NULL, *current;
+       identification_t *keyid = NULL;
+       public_key_t *public;
+       chunk_t chunk;
+       char *uri = NULL;
+
+       /** lookup cache for valid OCSP responses */
+       enumerator = create_cert_enumerator(this, CERT_X509_OCSP_RESPONSE,
+                                                                               KEY_ANY, NULL, FALSE);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               current->get_ref(current);
+               best = get_better_ocsp(this, current, best, subject, issuer,
+                                                          &valid, FALSE);
+               if (best && valid != VALIDATION_STALE)
+               {
+                       DBG1(DBG_CFG, "  using cached ocsp response");
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       /* derive the authorityKeyIdentifier from the issuer's public key */
+       current = &issuer->interface;
+       public = current->get_public_key(current);
+       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
+       {
+               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
+       }
+       /** fetch from configured OCSP responder URLs */
+       if (keyid && valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+       {
+               enumerator = create_cdp_enumerator(this, CERT_X509_OCSP_RESPONSE, keyid);
+               while (enumerator->enumerate(enumerator, &uri))
+               {
+                       current = fetch_ocsp(this, uri, &subject->interface,
+                                                                &issuer->interface);
+                       if (current)
+                       {
+                               best = get_better_ocsp(this, current, best, subject, issuer,
+                                                                          &valid, TRUE);
+                               if (best && valid != VALIDATION_STALE)
+                               {
+                                       break;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       DESTROY_IF(public);
+       DESTROY_IF(keyid);
+
+       /* fallback to URL fetching from subject certificate's URIs */
+       if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+       {
+               enumerator = subject->create_ocsp_uri_enumerator(subject);
+               while (enumerator->enumerate(enumerator, &uri))
+               {
+                       current = fetch_ocsp(this, uri, &subject->interface,
+                                                                &issuer->interface);
+                       if (current)
+                       {
+                               best = get_better_ocsp(this, current, best, subject, issuer,
+                                                                          &valid, TRUE);
+                               if (best && valid != VALIDATION_STALE)
+                               {
+                                       break;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       /* an uri was found, but no result. switch validation state to failed */
+       if (valid == VALIDATION_SKIPPED && uri)
+       {
+               valid = VALIDATION_FAILED;
+       }
+       if (auth)
+       {
+               auth->add(auth, AUTH_RULE_OCSP_VALIDATION, valid);
+               if (valid == VALIDATION_GOOD)
+               {       /* successful OCSP check fulfills also CRL constraint */
+                       auth->add(auth, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+               }
+       }
+       DESTROY_IF(best);
+       return valid;
+}
+
+/**
+ * fetch a CRL from an URL
+ */
+static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
+{
+       certificate_t *crl;
+       chunk_t chunk;
+
+       DBG1(DBG_CFG, "  fetching crl from '%s' ...", url);
+       if (lib->fetcher->fetch(lib->fetcher, url, &chunk, FETCH_END) != SUCCESS)
+       {
+               DBG1(DBG_CFG, "crl fetching failed");
+               return NULL;
+       }
+       crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
+                                                        BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+       chunk_free(&chunk);
+       if (!crl)
+       {
+               DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
+               return NULL;
+       }
+       return crl;
+}
+
+/**
+ * check the signature of an CRL
+ */
+static bool verify_crl(private_credential_manager_t *this, certificate_t *crl)
+{
+       certificate_t *issuer;
+       enumerator_t *enumerator;
+       bool verified = FALSE;
+
+       enumerator = create_trusted_enumerator(this, KEY_ANY, crl->get_issuer(crl),
+                                                                                  FALSE);
+       while (enumerator->enumerate(enumerator, &issuer, NULL))
+       {
+               if (this->cache->issued_by(this->cache, crl, issuer))
+               {
+                       DBG1(DBG_CFG, "  crl correctly signed by \"%Y\"",
+                                                  issuer->get_subject(issuer));
+                       verified = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       return verified;
+}
+
+/**
+ * Get the better of two CRLs, and check for usable CRL info
+ */
+static certificate_t *get_better_crl(private_credential_manager_t *this,
+                                                                        certificate_t *cand, certificate_t *best,
+                                                                        x509_t *subject, x509_t *issuer,
+                                                                        cert_validation_t *valid, bool cache)
+{
+       enumerator_t *enumerator;
+       time_t revocation, valid_until;
+       crl_reason_t reason;
+       chunk_t serial;
+       crl_t *crl;
+
+       /* check CRL signature */
+       if (!verify_crl(this, cand))
+       {
+               DBG1(DBG_CFG, "crl response verification failed");
+               cand->destroy(cand);
+               return best;
+       }
+
+       crl = (crl_t*)cand;
+       enumerator = crl->create_enumerator(crl);
+       while (enumerator->enumerate(enumerator, &serial, &revocation, &reason))
+       {
+               if (chunk_equals(serial, subject->get_serial(subject)))
+               {
+                       DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
+                                &revocation, TRUE, crl_reason_names, reason);
+                       *valid = VALIDATION_REVOKED;
+                       enumerator->destroy(enumerator);
+                       DESTROY_IF(best);
+                       return cand;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       /* select the better of the two CRLs */
+       if (best == NULL || crl_is_newer(crl, (crl_t*)best))
+       {
+               DESTROY_IF(best);
+               best = cand;
+               if (best->get_validity(best, NULL, NULL, &valid_until))
+               {
+                       DBG1(DBG_CFG, "  crl is valid: until %T", &valid_until, FALSE);
+                       *valid = VALIDATION_GOOD;
+                       if (cache)
+                       {       /* we cache non-stale crls only, as a stale crls are refetched */
+                               cache_cert(this, best);
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "  crl is stale: since %T", &valid_until, FALSE);
+                       *valid = VALIDATION_STALE;
+               }
+       }
+       else
+       {
+               *valid = VALIDATION_STALE;
+               cand->destroy(cand);
+       }
+       return best;
+}
+
+/**
+ * validate a x509 certificate using CRL
+ */
+static cert_validation_t check_crl(private_credential_manager_t *this,
+                                                                  x509_t *subject, x509_t *issuer,
+                                                                  auth_cfg_t *auth)
+{
+       cert_validation_t valid = VALIDATION_SKIPPED;
+       identification_t *keyid = NULL;
+       certificate_t *best = NULL;
+       certificate_t *current;
+       public_key_t *public;
+       enumerator_t *enumerator;
+       chunk_t chunk;
+       char *uri = NULL;
+
+       /* derive the authorityKeyIdentifier from the issuer's public key */
+       current = &issuer->interface;
+       public = current->get_public_key(current);
+       if (public && public->get_fingerprint(public, KEY_ID_PUBKEY_SHA1, &chunk))
+       {
+               keyid = identification_create_from_encoding(ID_KEY_ID, chunk);
+
+               /* find a cached crl by authorityKeyIdentifier */
+               enumerator = create_cert_enumerator(this, CERT_X509_CRL, KEY_ANY,
+                                                                                       keyid, FALSE);
+               while (enumerator->enumerate(enumerator, &current))
+               {
+                       current->get_ref(current);
+                       best = get_better_crl(this, current, best, subject, issuer,
+                                                                 &valid, FALSE);
+                       if (best && valid != VALIDATION_STALE)
+                       {
+                               DBG1(DBG_CFG, "  using cached crl");
+                               break;
+                       }
+               }
+               enumerator->destroy(enumerator);
+
+               /* fallback to fetching crls from credential sets cdps */
+               if (valid != VALIDATION_GOOD && valid != VALIDATION_REVOKED)
+               {
+                       enumerator = create_cdp_enumerator(this, CERT_X509_CRL, keyid);
+
+                       while (enumerator->enumerate(enumerator, &uri))
+                       {
+                               current = fetch_crl(this, uri);
+                               if (current)
+                               {
+                                       best = get_better_crl(this, current, best, subject, issuer,
+                                                                                 &valid, TRUE);
+                                       if (best && valid != VALIDATION_STALE)
+                                       {
+                                               break;
+                                       }
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+               }
+     &