merged multi-auth branch back into trunk
This commit is contained in:
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include "auth_info.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <credentials/certificates/certificate.h>
|
||||
|
||||
ENUM(auth_item_names, AUTHN_CA_CERT, AUTHZ_AC_GROUP,
|
||||
"AUTHN_AUTH_CLASS",
|
||||
"AUTHN_EAP_TYPE",
|
||||
"AUTHN_EAP_VENDOR",
|
||||
"AUTHN_EAP_IDENTITY",
|
||||
"AUTHN_CA_CERT",
|
||||
"AUTHN_CA_CERT_KEYID",
|
||||
"AUTHN_CA_CERT_NAME",
|
||||
"AUTHN_IM_CERT",
|
||||
"AUTHN_SUBJECT_CERT",
|
||||
"AUTHN_IM_HASH_URL",
|
||||
"AUTHN_SUBJECT_HASH_URL",
|
||||
"AUTHZ_PUBKEY",
|
||||
"AUTHZ_PSK",
|
||||
"AUTHZ_EAP",
|
||||
"AUTHZ_CA_CERT",
|
||||
"AUTHZ_CA_CERT_NAME",
|
||||
"AUTHZ_IM_CERT",
|
||||
"AUTHZ_SUBJECT_CERT",
|
||||
"AUTHZ_CRL_VALIDATION",
|
||||
"AUTHZ_OCSP_VALIDATION",
|
||||
"AUTHZ_AC_GROUP",
|
||||
);
|
||||
|
||||
typedef struct private_auth_info_t private_auth_info_t;
|
||||
|
||||
/**
|
||||
* private data of item_set
|
||||
*/
|
||||
struct private_auth_info_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
auth_info_t public;
|
||||
|
||||
/**
|
||||
* list of item_t's
|
||||
*/
|
||||
linked_list_t *items;
|
||||
};
|
||||
|
||||
typedef struct item_t item_t;
|
||||
|
||||
struct item_t {
|
||||
/** type of this item */
|
||||
auth_item_t type;
|
||||
/** associated privlege value, if any */
|
||||
void *value;
|
||||
};
|
||||
|
||||
/**
|
||||
* enumerator for auth_info_wrapper_t.create_cert_enumerator()
|
||||
*/
|
||||
typedef struct {
|
||||
/** implements enumerator_t */
|
||||
enumerator_t public;
|
||||
/** inner enumerator from linked_list_t */
|
||||
enumerator_t *inner;
|
||||
/** the current item */
|
||||
item_t *item;
|
||||
} item_enumerator_t;
|
||||
|
||||
/**
|
||||
* enumerate function for item_enumerator_t
|
||||
*/
|
||||
static bool enumerate(item_enumerator_t *this, auth_item_t *type, void **value)
|
||||
{
|
||||
if (this->inner->enumerate(this->inner, &this->item))
|
||||
{
|
||||
*type = this->item->type;
|
||||
*value = this->item->value;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy function for item_enumerator_t
|
||||
*/
|
||||
static void item_enumerator_destroy(item_enumerator_t *this)
|
||||
{
|
||||
this->inner->destroy(this->inner);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.create_item_enumerator.
|
||||
*/
|
||||
static enumerator_t* create_item_enumerator(private_auth_info_t *this)
|
||||
{
|
||||
item_enumerator_t *enumerator;
|
||||
|
||||
enumerator = malloc_thing(item_enumerator_t);
|
||||
enumerator->item = NULL;
|
||||
enumerator->inner = this->items->create_enumerator(this->items);
|
||||
enumerator->public.enumerate = (void*)enumerate;
|
||||
enumerator->public.destroy = (void*)item_enumerator_destroy;
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
static void destroy_item_value(item_t *item);
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.replace_item.
|
||||
*/
|
||||
static void replace_item(item_enumerator_t *enumerator, auth_item_t type, void *value)
|
||||
{
|
||||
destroy_item_value(enumerator->item);
|
||||
enumerator->item->type = type;
|
||||
enumerator->item->value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.get_item.
|
||||
*/
|
||||
static bool get_item(private_auth_info_t *this, auth_item_t type, void** value)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
void *current_value;
|
||||
auth_item_t current_type;
|
||||
bool found = FALSE;
|
||||
|
||||
enumerator = create_item_enumerator(this);
|
||||
while (enumerator->enumerate(enumerator, ¤t_type, ¤t_value))
|
||||
{
|
||||
if (type == current_type)
|
||||
{
|
||||
*value = current_value;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.add_item.
|
||||
*/
|
||||
static void add_item(private_auth_info_t *this, auth_item_t type, void *value)
|
||||
{
|
||||
item_t *item = malloc_thing(item_t);
|
||||
|
||||
item->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case AUTHZ_PUBKEY:
|
||||
{
|
||||
public_key_t *key = (public_key_t*)value;
|
||||
|
||||
item->value = key->get_ref(key);
|
||||
break;
|
||||
}
|
||||
case AUTHZ_PSK:
|
||||
{
|
||||
shared_key_t *key = (shared_key_t*)value;
|
||||
|
||||
item->value = key->get_ref(key);
|
||||
break;
|
||||
}
|
||||
case AUTHN_IM_HASH_URL:
|
||||
case AUTHN_SUBJECT_HASH_URL:
|
||||
{
|
||||
item->value = strdup(value);
|
||||
break;
|
||||
}
|
||||
case AUTHN_CA_CERT:
|
||||
case AUTHN_IM_CERT:
|
||||
case AUTHN_SUBJECT_CERT:
|
||||
case AUTHZ_CA_CERT:
|
||||
case AUTHZ_IM_CERT:
|
||||
case AUTHZ_SUBJECT_CERT:
|
||||
{
|
||||
certificate_t *cert = (certificate_t*)value;
|
||||
|
||||
item->value = cert->get_ref(cert);
|
||||
break;
|
||||
}
|
||||
case AUTHZ_CRL_VALIDATION:
|
||||
case AUTHZ_OCSP_VALIDATION:
|
||||
{
|
||||
cert_validation_t *validation = malloc_thing(cert_validation_t);
|
||||
|
||||
*validation = *(cert_validation_t*)value;
|
||||
item->value = validation;
|
||||
break;
|
||||
}
|
||||
case AUTHN_AUTH_CLASS:
|
||||
case AUTHN_EAP_TYPE:
|
||||
case AUTHN_EAP_VENDOR:
|
||||
case AUTHZ_EAP:
|
||||
{
|
||||
u_int *intval = malloc_thing(u_int);
|
||||
|
||||
*intval = *(u_int*)value;
|
||||
item->value = intval;
|
||||
break;
|
||||
}
|
||||
case AUTHN_EAP_IDENTITY:
|
||||
case AUTHN_CA_CERT_KEYID:
|
||||
case AUTHN_CA_CERT_NAME:
|
||||
case AUTHZ_CA_CERT_NAME:
|
||||
case AUTHZ_AC_GROUP:
|
||||
{
|
||||
identification_t *id = (identification_t*)value;
|
||||
|
||||
item->value = id->clone(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
this->items->insert_last(this->items, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.complies.
|
||||
*/
|
||||
static bool complies(private_auth_info_t *this, auth_info_t *constraints)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool success = TRUE;
|
||||
auth_item_t t1, t2;
|
||||
void *value;
|
||||
|
||||
enumerator = constraints->create_item_enumerator(constraints);
|
||||
while (enumerator->enumerate(enumerator, &t1, &value))
|
||||
{
|
||||
switch (t1)
|
||||
{
|
||||
case AUTHN_AUTH_CLASS:
|
||||
case AUTHN_EAP_TYPE:
|
||||
case AUTHN_EAP_VENDOR:
|
||||
case AUTHN_EAP_IDENTITY:
|
||||
case AUTHN_CA_CERT_KEYID:
|
||||
case AUTHN_CA_CERT:
|
||||
case AUTHN_CA_CERT_NAME:
|
||||
case AUTHN_IM_CERT:
|
||||
case AUTHN_SUBJECT_CERT:
|
||||
case AUTHN_IM_HASH_URL:
|
||||
case AUTHN_SUBJECT_HASH_URL:
|
||||
{ /* skip non-authorization tokens */
|
||||
continue;
|
||||
}
|
||||
case AUTHZ_CRL_VALIDATION:
|
||||
case AUTHZ_OCSP_VALIDATION:
|
||||
{
|
||||
cert_validation_t *valid;
|
||||
|
||||
/* OCSP validation is also sufficient for CRL constraint, but
|
||||
* not vice-versa */
|
||||
if (!get_item(this, t1, (void**)&valid) &&
|
||||
t1 == AUTHZ_CRL_VALIDATION &&
|
||||
!get_item(this, AUTHZ_OCSP_VALIDATION, (void**)&valid))
|
||||
{
|
||||
DBG1(DBG_CFG, "constraint check failed: %N requires at "
|
||||
"least %N, but no check done", auth_item_names, t1,
|
||||
cert_validation_names, *(cert_validation_t*)value);
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
switch (*(cert_validation_t*)value)
|
||||
{
|
||||
case VALIDATION_SKIPPED:
|
||||
if (*valid == VALIDATION_SKIPPED)
|
||||
{
|
||||
break;
|
||||
} /* FALL */
|
||||
case VALIDATION_GOOD:
|
||||
if (*valid == VALIDATION_GOOD)
|
||||
{
|
||||
break;
|
||||
} /* FALL */
|
||||
default:
|
||||
DBG1(DBG_CFG, "constraint check failed: %N is %N, but "
|
||||
"requires at least %N", auth_item_names, t1,
|
||||
cert_validation_names, *valid,
|
||||
cert_validation_names, *(cert_validation_t*)value);
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUTHZ_CA_CERT:
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *c1, *c2;
|
||||
|
||||
c1 = (certificate_t*)value;
|
||||
|
||||
success = FALSE;
|
||||
enumerator = create_item_enumerator(this);
|
||||
while (enumerator->enumerate(enumerator, &t2, &c2))
|
||||
{
|
||||
if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
|
||||
c1->equals(c1, c2))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!success)
|
||||
{
|
||||
DBG1(DBG_CFG, "constraint check failed: peer not "
|
||||
"authenticated by CA '%D'.", c1->get_subject(c1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUTHZ_CA_CERT_NAME:
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *cert;
|
||||
identification_t *id;
|
||||
|
||||
id = (identification_t*)value;
|
||||
success = FALSE;
|
||||
enumerator = create_item_enumerator(this);
|
||||
while (enumerator->enumerate(enumerator, &t2, &cert))
|
||||
{
|
||||
if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
|
||||
cert->has_subject(cert, id))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!success)
|
||||
{
|
||||
DBG1(DBG_CFG, "constraint check failed: peer not "
|
||||
"authenticated by CA '%D'.", id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUTHZ_PUBKEY:
|
||||
case AUTHZ_PSK:
|
||||
case AUTHZ_IM_CERT:
|
||||
case AUTHZ_SUBJECT_CERT:
|
||||
case AUTHZ_EAP:
|
||||
case AUTHZ_AC_GROUP:
|
||||
{
|
||||
DBG1(DBG_CFG, "constraint check %N not implemented!",
|
||||
auth_item_names, t1);
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.merge.
|
||||
*/
|
||||
static void merge(private_auth_info_t *this, private_auth_info_t *other)
|
||||
{
|
||||
item_t *item;
|
||||
|
||||
while (other->items->remove_first(other->items, (void**)&item) == SUCCESS)
|
||||
{
|
||||
this->items->insert_last(this->items, item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.equals.
|
||||
*/
|
||||
static bool equals(private_auth_info_t *this, private_auth_info_t *other)
|
||||
{
|
||||
enumerator_t *e1, *e2;
|
||||
item_t *i1, *i2;
|
||||
bool equal = TRUE, found;
|
||||
|
||||
e1 = this->items->create_enumerator(this->items);
|
||||
while (e1->enumerate(e1, &i1))
|
||||
{
|
||||
found = FALSE;
|
||||
e2 = other->items->create_enumerator(other->items);
|
||||
while (e2->enumerate(e2, &i2))
|
||||
{
|
||||
if (i1->type == i2->type)
|
||||
{
|
||||
switch (i1->type)
|
||||
{
|
||||
case AUTHZ_CRL_VALIDATION:
|
||||
case AUTHZ_OCSP_VALIDATION:
|
||||
{
|
||||
cert_validation_t c1, c2;
|
||||
|
||||
c1 = *(cert_validation_t*)i1->value;
|
||||
c2 = *(cert_validation_t*)i2->value;
|
||||
|
||||
if (c1 == c2)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case AUTHN_IM_HASH_URL:
|
||||
case AUTHN_SUBJECT_HASH_URL:
|
||||
{
|
||||
if (streq(i1->value, i2->value))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case AUTHN_CA_CERT:
|
||||
case AUTHN_IM_CERT:
|
||||
case AUTHN_SUBJECT_CERT:
|
||||
case AUTHZ_CA_CERT:
|
||||
case AUTHZ_IM_CERT:
|
||||
case AUTHZ_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 AUTHN_EAP_IDENTITY:
|
||||
case AUTHN_CA_CERT_KEYID:
|
||||
case AUTHN_CA_CERT_NAME:
|
||||
case AUTHZ_CA_CERT_NAME:
|
||||
{
|
||||
identification_t *c1, *c2;
|
||||
|
||||
c1 = (identification_t*)i1->value;
|
||||
c2 = (identification_t*)i2->value;
|
||||
|
||||
if (c1->equals(c1, c2))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
case AUTHN_AUTH_CLASS:
|
||||
case AUTHN_EAP_TYPE:
|
||||
case AUTHN_EAP_VENDOR:
|
||||
{
|
||||
if (*(u_int*)i1->value == *(u_int*)i2->value)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case AUTHZ_PUBKEY:
|
||||
case AUTHZ_PSK:
|
||||
case AUTHZ_EAP:
|
||||
case AUTHZ_AC_GROUP:
|
||||
/* TODO: implement value comparison */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
e2->destroy(e2);
|
||||
if (!found)
|
||||
{
|
||||
equal = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
return equal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the value associated with an item
|
||||
*/
|
||||
static void destroy_item_value(item_t *item)
|
||||
{
|
||||
switch (item->type)
|
||||
{
|
||||
case AUTHZ_PUBKEY:
|
||||
{
|
||||
public_key_t *key = (public_key_t*)item->value;
|
||||
key->destroy(key);
|
||||
break;
|
||||
}
|
||||
case AUTHZ_PSK:
|
||||
{
|
||||
shared_key_t *key = (shared_key_t*)item->value;
|
||||
key->destroy(key);
|
||||
break;
|
||||
}
|
||||
case AUTHN_CA_CERT:
|
||||
case AUTHN_IM_CERT:
|
||||
case AUTHN_SUBJECT_CERT:
|
||||
case AUTHZ_CA_CERT:
|
||||
case AUTHZ_IM_CERT:
|
||||
case AUTHZ_SUBJECT_CERT:
|
||||
{
|
||||
certificate_t *cert = (certificate_t*)item->value;
|
||||
cert->destroy(cert);
|
||||
break;
|
||||
}
|
||||
case AUTHN_AUTH_CLASS:
|
||||
case AUTHN_EAP_TYPE:
|
||||
case AUTHN_EAP_VENDOR:
|
||||
case AUTHN_IM_HASH_URL:
|
||||
case AUTHN_SUBJECT_HASH_URL:
|
||||
case AUTHZ_CRL_VALIDATION:
|
||||
case AUTHZ_OCSP_VALIDATION:
|
||||
case AUTHZ_EAP:
|
||||
{
|
||||
free(item->value);
|
||||
break;
|
||||
}
|
||||
case AUTHN_EAP_IDENTITY:
|
||||
case AUTHN_CA_CERT_KEYID:
|
||||
case AUTHN_CA_CERT_NAME:
|
||||
case AUTHZ_CA_CERT_NAME:
|
||||
case AUTHZ_AC_GROUP:
|
||||
{
|
||||
identification_t *id = (identification_t*)item->value;
|
||||
id->destroy(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.purge
|
||||
*/
|
||||
static void purge(private_auth_info_t *this)
|
||||
{
|
||||
item_t *item;
|
||||
|
||||
while (this->items->remove_last(this->items, (void**)&item) == SUCCESS)
|
||||
{
|
||||
destroy_item_value(item);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_info_t.destroy
|
||||
*/
|
||||
static void destroy(private_auth_info_t *this)
|
||||
{
|
||||
purge(this);
|
||||
this->items->destroy(this->items);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
auth_info_t *auth_info_create()
|
||||
{
|
||||
private_auth_info_t *this = malloc_thing(private_auth_info_t);
|
||||
|
||||
this->public.add_item = (void(*)(auth_info_t*, auth_item_t type, void *value))add_item;
|
||||
this->public.get_item = (bool(*)(auth_info_t*, auth_item_t type, void **value))get_item;
|
||||
this->public.replace_item = (void(*)(enumerator_t*,auth_item_t,void*))replace_item;
|
||||
this->public.create_item_enumerator = (enumerator_t*(*)(auth_info_t*))create_item_enumerator;
|
||||
this->public.complies = (bool(*)(auth_info_t*, auth_info_t *))complies;
|
||||
this->public.merge = (void(*)(auth_info_t*, auth_info_t *other))merge;
|
||||
this->public.purge = (void(*)(auth_info_t*))purge;
|
||||
this->public.equals = (bool(*)(auth_info_t*, auth_info_t *other))equals;
|
||||
this->public.destroy = (void(*)(auth_info_t*))destroy;
|
||||
|
||||
this->items = linked_list_create();
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* 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 auth_info auth_info
|
||||
* @{ @ingroup ccredentials
|
||||
*/
|
||||
|
||||
#ifndef AUTH_INFO_H_
|
||||
#define AUTH_INFO_H_
|
||||
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
typedef struct auth_info_t auth_info_t;
|
||||
typedef enum auth_item_t auth_item_t;
|
||||
|
||||
/**
|
||||
* Authentication/Authorization process helper item.
|
||||
*
|
||||
* For the authentication process, further information may be needed. These
|
||||
* items are defined as auth_item_t and have a AUTHN prefix.
|
||||
* The authentication process returns important data for the authorization
|
||||
* process, these items are defined with a AUTHZ prefix.
|
||||
* Authentication uses AUTHN items and creates AUTHZ items during authentication,
|
||||
* authorization reads AUTHZ values to give out privileges.
|
||||
*
|
||||
* +---+ +---------------------+
|
||||
* | A | | A |
|
||||
* | u | | u +-----------+ |
|
||||
* | t | | t | Required | |
|
||||
* | h | | h | auth_info | |
|
||||
* | e | | o +-----------+ |
|
||||
* | n | | r | |
|
||||
* +-----------+ | t | | i | |
|
||||
* | Provided | | i | | z V |
|
||||
* | auth_info |--| c |-------------| a ----> match? ----|------->
|
||||
* +-----------+ | a | | t |
|
||||
* | t | | i |
|
||||
* | i | | o |
|
||||
* | o | | n |
|
||||
* | n | | |
|
||||
* +---+ +---------------------+
|
||||
*/
|
||||
enum auth_item_t {
|
||||
|
||||
/*
|
||||
* items provided to authentication process
|
||||
*/
|
||||
|
||||
/** authentication class to use, value is auth_class_t* */
|
||||
AUTHN_AUTH_CLASS,
|
||||
/** EAP method to request from peer, value is eap_type_t* */
|
||||
AUTHN_EAP_TYPE,
|
||||
/** EAP vendor to used in conjunction with EAP method, value is u_int32_t* */
|
||||
AUTHN_EAP_VENDOR,
|
||||
/** EAP identity to use within EAP-Identity exchange */
|
||||
AUTHN_EAP_IDENTITY,
|
||||
/** CA certificate to use for authentication, value is certificate_t* */
|
||||
AUTHN_CA_CERT,
|
||||
/** Keyid of a CA certificate to use, value is identification_t* */
|
||||
AUTHN_CA_CERT_KEYID,
|
||||
/** subject DN of a CA certificate to use, value is identification_t* */
|
||||
AUTHN_CA_CERT_NAME,
|
||||
/** intermediate certificate, value is certificate_t* */
|
||||
AUTHN_IM_CERT,
|
||||
/** certificate for trustchain verification, value is certificate_t* */
|
||||
AUTHN_SUBJECT_CERT,
|
||||
/** intermediate certificate supplied as hash and url */
|
||||
AUTHN_IM_HASH_URL,
|
||||
/** end-entity certificate supplied as hash and url */
|
||||
AUTHN_SUBJECT_HASH_URL,
|
||||
|
||||
/*
|
||||
* item provided to authorization process
|
||||
*/
|
||||
|
||||
/** subject has been authenticated by public key, value is public_key_t* */
|
||||
AUTHZ_PUBKEY,
|
||||
/** subject has ben authenticated using preshared secrets, value is shared_key_t* */
|
||||
AUTHZ_PSK,
|
||||
/** subject has been authenticated using EAP, value is eap_type_t* */
|
||||
AUTHZ_EAP,
|
||||
/** certificate authority, value is certificate_t* */
|
||||
AUTHZ_CA_CERT,
|
||||
/** subject DN of a certificate authority, value is identification_t* */
|
||||
AUTHZ_CA_CERT_NAME,
|
||||
/** intermediate certificate in trustchain, value is certificate_t* */
|
||||
AUTHZ_IM_CERT,
|
||||
/** subject certificate, value is certificate_t* */
|
||||
AUTHZ_SUBJECT_CERT,
|
||||
/** result of a CRL validation, value is cert_validation_t */
|
||||
AUTHZ_CRL_VALIDATION,
|
||||
/** result of a OCSP validation, value is cert_validation_t */
|
||||
AUTHZ_OCSP_VALIDATION,
|
||||
/** subject is in attribute certificate group, value is identification_t* */
|
||||
AUTHZ_AC_GROUP,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* enum name for auth_item_t.
|
||||
*/
|
||||
extern enum_name_t *auth_item_names;
|
||||
|
||||
/**
|
||||
* The auth_info class contains auth_item_t's used for AA.
|
||||
*
|
||||
* A auth_info allows the separation of authentication and authorization.
|
||||
*/
|
||||
struct auth_info_t {
|
||||
|
||||
/**
|
||||
* Add an item to the set.
|
||||
*
|
||||
* @param type auth_info type
|
||||
* @param value associated value to auth_info type, if any
|
||||
*/
|
||||
void (*add_item)(auth_info_t *this, auth_item_t type, void *value);
|
||||
|
||||
/**
|
||||
* Get an item.
|
||||
*
|
||||
* @param type auth_info type to get
|
||||
* @param value pointer to a pointer receiving item
|
||||
* @return bool if item has been found
|
||||
*/
|
||||
bool (*get_item)(auth_info_t *this, auth_item_t type, void **value);
|
||||
|
||||
/**
|
||||
* Replace an item.
|
||||
*
|
||||
* @param type new auth_info type
|
||||
* @param value pointer to the new value
|
||||
*/
|
||||
void (*replace_item)(enumerator_t *this, auth_item_t type, void *value);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all items.
|
||||
*
|
||||
* @return enumerator over (auth_item_t type, void *value)
|
||||
*/
|
||||
enumerator_t* (*create_item_enumerator)(auth_info_t *this);
|
||||
|
||||
/**
|
||||
* Check if this fulfills a set of required constraints.
|
||||
*
|
||||
* @param constraints required authorization infos
|
||||
* @return TRUE if this complies with constraints
|
||||
*/
|
||||
bool (*complies)(auth_info_t *this, auth_info_t *constraints);
|
||||
|
||||
/**
|
||||
* Merge items from other into this.
|
||||
*
|
||||
* Items do not get cloned, but moved from other to this.
|
||||
*
|
||||
* @param other items to read for merge
|
||||
*/
|
||||
void (*merge)(auth_info_t *this, auth_info_t *other);
|
||||
|
||||
/**
|
||||
* Purge all items in auth_info.
|
||||
*/
|
||||
void (*purge)(auth_info_t *this);
|
||||
|
||||
/**
|
||||
* Check two auth_infos for equality.
|
||||
*
|
||||
* @param other other item to compaire against this
|
||||
* @return TRUE if auth infos identical
|
||||
*/
|
||||
bool (*equals)(auth_info_t *this, auth_info_t *other);
|
||||
|
||||
/**
|
||||
* Destroy a auth_info instance with all associated values.
|
||||
*/
|
||||
void (*destroy)(auth_info_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a auth_info instance.
|
||||
*/
|
||||
auth_info_t *auth_info_create();
|
||||
|
||||
#endif /** AUTH_INFO_H_ @}*/
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <utils/mutex.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <credentials/sets/cert_cache.h>
|
||||
#include <credentials/sets/auth_info_wrapper.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>
|
||||
@@ -625,7 +625,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
|
||||
*/
|
||||
static cert_validation_t check_ocsp(private_credential_manager_t *this,
|
||||
x509_t *subject, x509_t *issuer,
|
||||
auth_info_t *auth)
|
||||
auth_cfg_t *auth)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
cert_validation_t valid = VALIDATION_SKIPPED;
|
||||
@@ -706,7 +706,11 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
|
||||
}
|
||||
if (auth)
|
||||
{
|
||||
auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
|
||||
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;
|
||||
@@ -728,6 +732,7 @@ static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
|
||||
}
|
||||
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");
|
||||
@@ -833,7 +838,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
|
||||
*/
|
||||
static cert_validation_t check_crl(private_credential_manager_t *this,
|
||||
x509_t *subject, x509_t *issuer,
|
||||
auth_info_t *auth)
|
||||
auth_cfg_t *auth)
|
||||
{
|
||||
cert_validation_t valid = VALIDATION_SKIPPED;
|
||||
identification_t *keyid = NULL;
|
||||
@@ -841,7 +846,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
|
||||
certificate_t *current;
|
||||
public_key_t *public;
|
||||
enumerator_t *enumerator;
|
||||
char *uri;
|
||||
char *uri = NULL;
|
||||
|
||||
/* derive the authorityKeyIdentifier from the issuer's public key */
|
||||
current = &issuer->interface;
|
||||
@@ -920,7 +925,16 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
|
||||
}
|
||||
if (auth)
|
||||
{
|
||||
auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
|
||||
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;
|
||||
@@ -931,7 +945,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
|
||||
*/
|
||||
static bool check_certificate(private_credential_manager_t *this,
|
||||
certificate_t *subject, certificate_t *issuer,
|
||||
bool crl, bool ocsp, auth_info_t *auth)
|
||||
bool crl, bool ocsp, auth_cfg_t *auth)
|
||||
{
|
||||
time_t not_before, not_after;
|
||||
|
||||
@@ -963,7 +977,7 @@ static bool check_certificate(private_credential_manager_t *this,
|
||||
DBG1(DBG_CFG, "certificate status is good");
|
||||
return TRUE;
|
||||
case VALIDATION_REVOKED:
|
||||
/* has already been logged */
|
||||
/* has already been logged */
|
||||
return FALSE;
|
||||
case VALIDATION_SKIPPED:
|
||||
DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
|
||||
@@ -983,8 +997,8 @@ static bool check_certificate(private_credential_manager_t *this,
|
||||
case VALIDATION_GOOD:
|
||||
DBG1(DBG_CFG, "certificate status is good");
|
||||
return TRUE;
|
||||
case VALIDATION_REVOKED:
|
||||
/* has already been logged */
|
||||
case VALIDATION_REVOKED:
|
||||
/* has already been logged */
|
||||
return FALSE;
|
||||
case VALIDATION_FAILED:
|
||||
case VALIDATION_SKIPPED:
|
||||
@@ -1050,14 +1064,14 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this,
|
||||
* 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_info_t *result,
|
||||
certificate_t *subject, auth_cfg_t *result,
|
||||
bool trusted, bool crl, bool ocsp)
|
||||
{
|
||||
certificate_t *current, *issuer;
|
||||
auth_info_t *auth;
|
||||
auth_cfg_t *auth;
|
||||
u_int level = 0;
|
||||
|
||||
auth = auth_info_create();
|
||||
auth = auth_cfg_create();
|
||||
current = subject->get_ref(subject);
|
||||
while (level++ < MAX_CA_LEVELS)
|
||||
{
|
||||
@@ -1067,14 +1081,14 @@ static bool verify_trust_chain(private_credential_manager_t *this,
|
||||
/* accept only self-signed CAs as trust anchor */
|
||||
if (this->cache->issued_by(this->cache, issuer, issuer))
|
||||
{
|
||||
auth->add_item(auth, AUTHZ_CA_CERT, issuer);
|
||||
auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
|
||||
DBG1(DBG_CFG, " using trusted ca certificate \"%D\"",
|
||||
issuer->get_subject(issuer));
|
||||
trusted = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
auth->add_item(auth, AUTHZ_IM_CERT, issuer);
|
||||
auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
|
||||
DBG1(DBG_CFG, " using trusted intermediate ca certificate "
|
||||
"\"%D\"", issuer->get_subject(issuer));
|
||||
}
|
||||
@@ -1091,7 +1105,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
|
||||
issuer->destroy(issuer);
|
||||
break;
|
||||
}
|
||||
auth->add_item(auth, AUTHZ_IM_CERT, issuer);
|
||||
auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
|
||||
DBG1(DBG_CFG, " using untrusted intermediate certificate "
|
||||
"\"%D\"", issuer->get_subject(issuer));
|
||||
}
|
||||
@@ -1123,7 +1137,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
|
||||
}
|
||||
if (trusted)
|
||||
{
|
||||
result->merge(result, auth);
|
||||
result->merge(result, auth, FALSE);
|
||||
}
|
||||
auth->destroy(auth);
|
||||
return trusted;
|
||||
@@ -1149,20 +1163,20 @@ typedef struct {
|
||||
bool ocsp;
|
||||
/** pretrusted certificate we have served at first invocation */
|
||||
certificate_t *pretrusted;
|
||||
/** currently enumerating auth info */
|
||||
auth_info_t *auth;
|
||||
/** 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_info_t **auth)
|
||||
certificate_t **cert, auth_cfg_t **auth)
|
||||
{
|
||||
certificate_t *current;
|
||||
|
||||
DESTROY_IF(this->auth);
|
||||
this->auth = auth_info_create();
|
||||
this->auth = auth_cfg_create();
|
||||
|
||||
if (!this->candidates)
|
||||
{
|
||||
@@ -1181,7 +1195,8 @@ static bool trusted_enumerate(trusted_enumerator_t *this,
|
||||
verify_trust_chain(this->this, this->pretrusted, this->auth,
|
||||
TRUE, this->crl, this->ocsp))
|
||||
{
|
||||
this->auth->add_item(this->auth, AUTHZ_CA_CERT, this->pretrusted);
|
||||
this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT,
|
||||
this->pretrusted->get_ref(this->pretrusted));
|
||||
DBG1(DBG_CFG, " using trusted certificate \"%D\"",
|
||||
this->pretrusted->get_subject(this->pretrusted));
|
||||
*cert = this->pretrusted;
|
||||
@@ -1264,15 +1279,15 @@ typedef struct {
|
||||
private_credential_manager_t *this;
|
||||
/** currently enumerating key */
|
||||
public_key_t *current;
|
||||
/** credset wrapper around auth */
|
||||
auth_info_wrapper_t *wrapper;
|
||||
/** 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_info_t **auth)
|
||||
public_key_t **key, auth_cfg_t **auth)
|
||||
{
|
||||
certificate_t *cert;
|
||||
|
||||
@@ -1312,7 +1327,7 @@ static void public_destroy(public_enumerator_t *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_info_t *auth)
|
||||
key_type_t type, identification_t *id, auth_cfg_t *auth)
|
||||
{
|
||||
public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
|
||||
|
||||
@@ -1324,7 +1339,7 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
|
||||
enumerator->wrapper = NULL;
|
||||
if (auth)
|
||||
{
|
||||
enumerator->wrapper = auth_info_wrapper_create(auth);
|
||||
enumerator->wrapper = auth_cfg_wrapper_create(auth);
|
||||
add_local_set(this, &enumerator->wrapper->set);
|
||||
}
|
||||
this->lock->read_lock(this->lock);
|
||||
@@ -1334,40 +1349,22 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
|
||||
/**
|
||||
* Check if a certificate's keyid is contained in the auth helper
|
||||
*/
|
||||
static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
|
||||
static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
identification_t *value;
|
||||
auth_item_t type;
|
||||
auth_rule_t type;
|
||||
bool found = FALSE;
|
||||
|
||||
enumerator = auth->create_item_enumerator(auth);
|
||||
enumerator = auth->create_enumerator(auth);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
|
||||
if (type == AUTH_RULE_CA_CERT &&
|
||||
cert->equals(cert, (certificate_t*)value))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
if (type == AUTHN_CA_CERT_KEYID)
|
||||
{
|
||||
public_key_t *public;
|
||||
identification_t *certid, *keyid;
|
||||
|
||||
public = cert->get_public_key(cert);
|
||||
if (public)
|
||||
{
|
||||
keyid = (identification_t*)value;
|
||||
certid = public->get_id(public, keyid->get_type(keyid));
|
||||
if (certid && certid->equals(certid, keyid))
|
||||
{
|
||||
public->destroy(public);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
public->destroy(public);
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return found;
|
||||
@@ -1376,19 +1373,21 @@ static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
|
||||
/**
|
||||
* build a trustchain from subject up to a trust anchor in trusted
|
||||
*/
|
||||
static auth_info_t *build_trustchain(private_credential_manager_t *this,
|
||||
certificate_t *subject, auth_info_t *auth)
|
||||
static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
|
||||
certificate_t *subject, auth_cfg_t *auth)
|
||||
{
|
||||
certificate_t *issuer, *current;
|
||||
auth_info_t *trustchain;
|
||||
auth_cfg_t *trustchain;
|
||||
u_int level = 0;
|
||||
|
||||
trustchain = auth_info_create();
|
||||
trustchain = auth_cfg_create();
|
||||
|
||||
if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)¤t))
|
||||
current = auth->get(auth, AUTH_RULE_CA_CERT);
|
||||
if (!current)
|
||||
{
|
||||
/* no trust anchor specified, return this cert only */
|
||||
trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
|
||||
trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT,
|
||||
subject->get_ref(subject));
|
||||
return trustchain;
|
||||
}
|
||||
current = subject->get_ref(subject);
|
||||
@@ -1396,26 +1395,23 @@ static auth_info_t *build_trustchain(private_credential_manager_t *this,
|
||||
{
|
||||
if (auth_contains_cacert(auth, current))
|
||||
{
|
||||
trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
|
||||
current->destroy(current);
|
||||
trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
|
||||
return trustchain;
|
||||
}
|
||||
if (subject == current)
|
||||
{
|
||||
trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
|
||||
trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT, current);
|
||||
}
|
||||
else
|
||||
{
|
||||
trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
|
||||
trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
|
||||
}
|
||||
issuer = get_issuer_cert(this, current, FALSE);
|
||||
if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
|
||||
{
|
||||
DESTROY_IF(issuer);
|
||||
current->destroy(current);
|
||||
break;
|
||||
}
|
||||
current->destroy(current);
|
||||
current = issuer;
|
||||
level++;
|
||||
}
|
||||
@@ -1451,12 +1447,12 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
|
||||
*/
|
||||
static private_key_t *get_private(private_credential_manager_t *this,
|
||||
key_type_t type, identification_t *id,
|
||||
auth_info_t *auth)
|
||||
auth_cfg_t *auth)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
certificate_t *cert;
|
||||
private_key_t *private = NULL;
|
||||
auth_info_t *trustchain;
|
||||
auth_cfg_t *trustchain;
|
||||
|
||||
/* check if this is a lookup by key ID, and do it if so */
|
||||
if (id)
|
||||
@@ -1471,8 +1467,25 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to build a trustchain for each certificate found */
|
||||
|
||||
/* 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))
|
||||
{
|
||||
@@ -1482,7 +1495,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
||||
trustchain = build_trustchain(this, cert, auth);
|
||||
if (trustchain)
|
||||
{
|
||||
auth->merge(auth, trustchain);
|
||||
auth->merge(auth, trustchain, FALSE);
|
||||
trustchain->destroy(trustchain);
|
||||
break;
|
||||
}
|
||||
@@ -1491,6 +1504,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* if no valid trustchain was found, fall back to the first usable cert */
|
||||
if (!private)
|
||||
{
|
||||
@@ -1500,7 +1514,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
|
||||
private = get_private_by_cert(this, cert, type);
|
||||
if (private)
|
||||
{
|
||||
auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
|
||||
auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1566,8 +1580,8 @@ credential_manager_t *credential_manager_create()
|
||||
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_info_t*))get_private;
|
||||
this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_info_t *aut))create_public_enumerator;
|
||||
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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2007-2008 Martin Willi
|
||||
* Copyright (C) 2007-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <utils/identification.h>
|
||||
#include <utils/enumerator.h>
|
||||
#include <credentials/auth_info.h>
|
||||
#include <config/auth_cfg.h>
|
||||
#include <credentials/credential_set.h>
|
||||
#include <credentials/keys/private_key.h>
|
||||
#include <credentials/keys/shared_key.h>
|
||||
@@ -122,7 +122,6 @@ struct credential_manager_t {
|
||||
* @param type kind of requested shared key
|
||||
* @param me own identity
|
||||
* @param other peers identity
|
||||
* @param auth auth_info helper
|
||||
* @return shared_key_t, NULL if none found
|
||||
*/
|
||||
shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
|
||||
@@ -138,11 +137,11 @@ struct credential_manager_t {
|
||||
*
|
||||
* @param type type of the key to get
|
||||
* @param id identification the key belongs to
|
||||
* @param auth auth_info helper, including trusted CA certificates
|
||||
* @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_info_t *auth);
|
||||
identification_t *id, auth_cfg_t *auth);
|
||||
|
||||
/**
|
||||
* Create an enumerator over trusted public keys.
|
||||
@@ -150,9 +149,8 @@ struct credential_manager_t {
|
||||
* 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_info_t *,
|
||||
* where the auth info contains gained privileges for the authorization
|
||||
* process.
|
||||
* 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
|
||||
@@ -160,7 +158,7 @@ struct credential_manager_t {
|
||||
* @return enumerator
|
||||
*/
|
||||
enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
|
||||
key_type_t type, identification_t *id, auth_info_t *auth);
|
||||
key_type_t type, identification_t *id, auth_cfg_t *auth);
|
||||
|
||||
/**
|
||||
* Cache a certificate by invoking cache_cert() on all registerd sets.
|
||||
|
||||
+47
-38
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -18,36 +18,36 @@
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
#include "auth_info_wrapper.h"
|
||||
#include "auth_cfg_wrapper.h"
|
||||
|
||||
typedef struct private_auth_info_wrapper_t private_auth_info_wrapper_t;
|
||||
typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t;
|
||||
|
||||
/**
|
||||
* private data of auth_info_wrapper
|
||||
* private data of auth_cfg_wrapper
|
||||
*/
|
||||
struct private_auth_info_wrapper_t {
|
||||
struct private_auth_cfg_wrapper_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
auth_info_wrapper_t public;
|
||||
auth_cfg_wrapper_t public;
|
||||
|
||||
/**
|
||||
* wrapped auth info
|
||||
*/
|
||||
auth_info_t *auth;
|
||||
auth_cfg_t *auth;
|
||||
};
|
||||
|
||||
/**
|
||||
* enumerator for auth_info_wrapper_t.create_cert_enumerator()
|
||||
* enumerator for auth_cfg_wrapper_t.create_cert_enumerator()
|
||||
*/
|
||||
typedef struct {
|
||||
/** implements enumerator_t */
|
||||
enumerator_t public;
|
||||
/** inner enumerator from auth_info */
|
||||
/** inner enumerator from auth_cfg */
|
||||
enumerator_t *inner;
|
||||
/** wrapped auth info */
|
||||
auth_info_t *auth;
|
||||
/** wrapped auth round */
|
||||
auth_cfg_t *auth;
|
||||
/** enumerated cert type */
|
||||
certificate_type_t cert;
|
||||
/** enumerated key type */
|
||||
@@ -57,10 +57,11 @@ typedef struct {
|
||||
} wrapper_enumerator_t;
|
||||
|
||||
/**
|
||||
* Tries to fetch a certificate that was supplied as "Hash and URL" (replaces the
|
||||
* item's type and value in place).
|
||||
* 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_item_t *type, void **value)
|
||||
static bool fetch_cert(wrapper_enumerator_t *enumerator,
|
||||
auth_rule_t *rule, void **value)
|
||||
{
|
||||
char *url = (char*)*value;
|
||||
if (!url)
|
||||
@@ -77,29 +78,38 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
|
||||
{
|
||||
DBG1(DBG_CFG, " fetching certificate failed");
|
||||
/* we set the item to NULL, so we can skip it */
|
||||
enumerator->auth->replace_item(enumerator->inner, *type, NULL);
|
||||
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);
|
||||
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_item(enumerator->inner, *type, NULL);
|
||||
enumerator->auth->replace(enumerator->auth, enumerator->inner,
|
||||
*rule, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DBG1(DBG_CFG, " fetched certificate \"%D\"", cert->get_subject(cert));
|
||||
charon->credentials->cache_cert(charon->credentials, cert);
|
||||
|
||||
*type = (*type == AUTHN_IM_HASH_URL) ? AUTHN_IM_CERT : AUTHN_SUBJECT_CERT;
|
||||
if (*rule == AUTH_HELPER_IM_HASH_URL)
|
||||
{
|
||||
*rule = AUTH_HELPER_IM_CERT;
|
||||
}
|
||||
else
|
||||
{
|
||||
*rule = AUTH_HELPER_SUBJECT_CERT;
|
||||
}
|
||||
*value = cert;
|
||||
enumerator->auth->replace_item(enumerator->inner, *type, cert);
|
||||
|
||||
enumerator->auth->replace(enumerator->auth, enumerator->inner,
|
||||
*rule, cert->get_ref(cert));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -108,26 +118,25 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
|
||||
*/
|
||||
static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
|
||||
{
|
||||
auth_item_t type;
|
||||
auth_rule_t rule;
|
||||
certificate_t *current;
|
||||
public_key_t *public;
|
||||
|
||||
while (this->inner->enumerate(this->inner, &type, ¤t))
|
||||
while (this->inner->enumerate(this->inner, &rule, ¤t))
|
||||
{
|
||||
if (type == AUTHN_IM_HASH_URL ||
|
||||
type == AUTHN_SUBJECT_HASH_URL)
|
||||
{
|
||||
if (!fetch_cert(this, &type, (void**)¤t))
|
||||
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**)¤t))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (type != AUTHN_SUBJECT_CERT &&
|
||||
type != AUTHN_IM_CERT)
|
||||
{
|
||||
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;
|
||||
@@ -164,9 +173,9 @@ static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation of auth_info_wrapper_t.set.create_cert_enumerator
|
||||
* implementation of auth_cfg_wrapper_t.set.create_cert_enumerator
|
||||
*/
|
||||
static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
|
||||
static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
|
||||
certificate_type_t cert, key_type_t key,
|
||||
identification_t *id, bool trusted)
|
||||
{
|
||||
@@ -181,16 +190,16 @@ static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
|
||||
enumerator->cert = cert;
|
||||
enumerator->key = key;
|
||||
enumerator->id = id;
|
||||
enumerator->inner = this->auth->create_item_enumerator(this->auth);
|
||||
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_info_wrapper_t.destroy
|
||||
* Implementation of auth_cfg_wrapper_t.destroy
|
||||
*/
|
||||
static void destroy(private_auth_info_wrapper_t *this)
|
||||
static void destroy(private_auth_cfg_wrapper_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
@@ -198,16 +207,16 @@ static void destroy(private_auth_info_wrapper_t *this)
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth)
|
||||
auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
|
||||
{
|
||||
private_auth_info_wrapper_t *this = malloc_thing(private_auth_info_wrapper_t);
|
||||
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_info_wrapper_t*))destroy;
|
||||
this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy;
|
||||
|
||||
this->auth = auth;
|
||||
|
||||
+13
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -16,22 +16,22 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup auth_info_wrapper auth_info_wrapper
|
||||
* @defgroup auth_cfg_wrapper auth_cfg_wrapper
|
||||
* @{ @ingroup sets
|
||||
*/
|
||||
|
||||
#ifndef AUTH_INFO_WRAPPER_H_
|
||||
#define AUTH_INFO_WRAPPER_H_
|
||||
#ifndef AUTH_CFG_WRAPPER_H_
|
||||
#define AUTH_CFG_WRAPPER_H_
|
||||
|
||||
#include <config/auth_cfg.h>
|
||||
#include <credentials/credential_set.h>
|
||||
#include <credentials/auth_info.h>
|
||||
|
||||
typedef struct auth_info_wrapper_t auth_info_wrapper_t;
|
||||
typedef struct auth_cfg_wrapper_t auth_cfg_wrapper_t;
|
||||
|
||||
/**
|
||||
* A wrapper around auth_info_t to handle it like a credential set.
|
||||
* A wrapper around auth_cfg_t to handle it as a credential set.
|
||||
*/
|
||||
struct auth_info_wrapper_t {
|
||||
struct auth_cfg_wrapper_t {
|
||||
|
||||
/**
|
||||
* implements credential_set_t
|
||||
@@ -39,17 +39,17 @@ struct auth_info_wrapper_t {
|
||||
credential_set_t set;
|
||||
|
||||
/**
|
||||
* Destroy a auth_info_wrapper instance.
|
||||
* Destroy a auth_cfg_wrapper instance.
|
||||
*/
|
||||
void (*destroy)(auth_info_wrapper_t *this);
|
||||
void (*destroy)(auth_cfg_wrapper_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a auth_info_wrapper instance.
|
||||
* Create a auth_cfg_wrapper instance.
|
||||
*
|
||||
* @param auth the wrapped auth info
|
||||
* @return wrapper around auth
|
||||
*/
|
||||
auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth);
|
||||
auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth);
|
||||
|
||||
#endif /** AUTH_INFO_WRAPPER_H_ @}*/
|
||||
#endif /** AUTH_CFG_WRAPPER_H_ @}*/
|
||||
Reference in New Issue
Block a user