aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/credentials/sets/auth_info_wrapper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/credentials/sets/auth_info_wrapper.c')
-rw-r--r--src/charon/credentials/sets/auth_info_wrapper.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/src/charon/credentials/sets/auth_info_wrapper.c b/src/charon/credentials/sets/auth_info_wrapper.c
index b7576a5a7..cdbe2bc57 100644
--- a/src/charon/credentials/sets/auth_info_wrapper.c
+++ b/src/charon/credentials/sets/auth_info_wrapper.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -15,6 +16,8 @@
* $Id$
*/
+#include <daemon.h>
+
#include "auth_info_wrapper.h"
typedef struct private_auth_info_wrapper_t private_auth_info_wrapper_t;
@@ -43,6 +46,8 @@ typedef struct {
enumerator_t public;
/** inner enumerator from auth_info */
enumerator_t *inner;
+ /** wrapped auth info */
+ auth_info_t *auth;
/** enumerated cert type */
certificate_type_t cert;
/** enumerated key type */
@@ -52,6 +57,52 @@ 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).
+ */
+static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, 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) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "fetching certificate from '%s' failed", url);
+ /* we set the item to NULL, so we can skip it */
+ enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+ return FALSE;
+ }
+
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, data, BUILD_END);
+
+ 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);
+ 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;
+ *value = cert;
+ enumerator->auth->replace_item(enumerator->inner, *type, cert);
+
+ return TRUE;
+}
+
+/**
* enumerate function for wrapper_enumerator_t
*/
static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
@@ -62,8 +113,16 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
while (this->inner->enumerate(this->inner, &type, &current))
{
- if (type != AUTHN_SUBJECT_CERT &&
- type != AUTHN_IM_CERT)
+ if (type == AUTHN_IM_HASH_URL ||
+ type == AUTHN_SUBJECT_HASH_URL)
+ {
+ if (!fetch_cert(this, &type, (void**)&current))
+ {
+ continue;
+ }
+ }
+ else if (type != AUTHN_SUBJECT_CERT &&
+ type != AUTHN_IM_CERT)
{
continue;
}
@@ -117,6 +176,7 @@ static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
return NULL;
}
enumerator = malloc_thing(wrapper_enumerator_t);
+ enumerator->auth = this->auth;
enumerator->cert = cert;
enumerator->key = key;
enumerator->id = id;