766 lines
16 KiB
C
766 lines
16 KiB
C
/* Dynamic fetching of X.509 CRLs
|
|
* Copyright (C) 2002 Stephane Laroche <stephane.laroche@colubris.com>
|
|
* Copyright (C) 2002-2009 Andreas Steffen - 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 <stdlib.h>
|
|
#include <errno.h>
|
|
#include <sys/time.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
|
|
#ifdef THREADS
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
#include <freeswan.h>
|
|
|
|
#include <library.h>
|
|
#include <debug.h>
|
|
#include <asn1/asn1.h>
|
|
#include <credentials/certificates/certificate.h>
|
|
#ifdef THREADS
|
|
#include <threading/thread.h>
|
|
#endif
|
|
|
|
#include "constants.h"
|
|
#include "defs.h"
|
|
#include "log.h"
|
|
#include "x509.h"
|
|
#include "ca.h"
|
|
#include "whack.h"
|
|
#include "ocsp.h"
|
|
#include "crl.h"
|
|
#include "fetch.h"
|
|
#include "builder.h"
|
|
|
|
fetch_req_t empty_fetch_req = {
|
|
NULL , /* next */
|
|
0 , /* trials */
|
|
NULL , /* issuer */
|
|
{ NULL, 0}, /* authKeyID */
|
|
NULL /* distributionPoints */
|
|
};
|
|
|
|
/* chained list of crl fetch requests */
|
|
static fetch_req_t *crl_fetch_reqs = NULL;
|
|
|
|
/* chained list of ocsp fetch requests */
|
|
static ocsp_location_t *ocsp_fetch_reqs = NULL;
|
|
|
|
#ifdef THREADS
|
|
static thread_t *thread;
|
|
static pthread_mutex_t certs_and_keys_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t authcert_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t crl_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t ocsp_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t ca_info_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t crl_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t ocsp_fetch_list_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_mutex_t fetch_wake_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
static pthread_cond_t fetch_wake_cond = PTHREAD_COND_INITIALIZER;
|
|
|
|
/**
|
|
* lock access to my certs and keys
|
|
*/
|
|
void lock_certs_and_keys(const char *who)
|
|
{
|
|
pthread_mutex_lock(&certs_and_keys_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("certs and keys locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to my certs and keys
|
|
*/
|
|
void unlock_certs_and_keys(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("certs and keys unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&certs_and_keys_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the chained authcert list
|
|
*/
|
|
void lock_authcert_list(const char *who)
|
|
{
|
|
pthread_mutex_lock(&authcert_list_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("authcert list locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the chained authcert list
|
|
*/
|
|
void unlock_authcert_list(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("authcert list unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&authcert_list_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the chained crl list
|
|
*/
|
|
void lock_crl_list(const char *who)
|
|
{
|
|
pthread_mutex_lock(&crl_list_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("crl list locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the chained crl list
|
|
*/
|
|
void unlock_crl_list(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("crl list unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&crl_list_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the ocsp cache
|
|
*/
|
|
extern void lock_ocsp_cache(const char *who)
|
|
{
|
|
pthread_mutex_lock(&ocsp_cache_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ocsp cache locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the ocsp cache
|
|
*/
|
|
extern void unlock_ocsp_cache(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ocsp cache unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&ocsp_cache_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the ca info list
|
|
*/
|
|
extern void lock_ca_info_list(const char *who)
|
|
{
|
|
pthread_mutex_lock(&ca_info_list_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ca info list locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the ca info list
|
|
*/
|
|
extern void unlock_ca_info_list(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ca info list unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&ca_info_list_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the chained crl fetch request list
|
|
*/
|
|
static void lock_crl_fetch_list(const char *who)
|
|
{
|
|
pthread_mutex_lock(&crl_fetch_list_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("crl fetch request list locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the chained crl fetch request list
|
|
*/
|
|
static void unlock_crl_fetch_list(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("crl fetch request list unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&crl_fetch_list_mutex);
|
|
}
|
|
|
|
/**
|
|
* Lock access to the chained ocsp fetch request list
|
|
*/
|
|
static void lock_ocsp_fetch_list(const char *who)
|
|
{
|
|
pthread_mutex_lock(&ocsp_fetch_list_mutex);
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ocsp fetch request list locked by '%s'", who)
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Unlock access to the chained ocsp fetch request list
|
|
*/
|
|
static void unlock_ocsp_fetch_list(const char *who)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("ocsp fetch request list unlocked by '%s'", who)
|
|
)
|
|
pthread_mutex_unlock(&ocsp_fetch_list_mutex);
|
|
}
|
|
|
|
/**
|
|
* Wakes up the sleeping fetch thread
|
|
*/
|
|
void wake_fetch_thread(const char *who)
|
|
{
|
|
if (crl_check_interval > 0)
|
|
{
|
|
DBG(DBG_CONTROLMORE,
|
|
DBG_log("fetch thread wake call by '%s'", who)
|
|
)
|
|
pthread_mutex_lock(&fetch_wake_mutex);
|
|
pthread_cond_signal(&fetch_wake_cond);
|
|
pthread_mutex_unlock(&fetch_wake_mutex);
|
|
}
|
|
}
|
|
#else /* !THREADS */
|
|
#define lock_crl_fetch_list(who) /* do nothing */
|
|
#define unlock_crl_fetch_list(who) /* do nothing */
|
|
#define lock_ocsp_fetch_list(who) /* do nothing */
|
|
#define unlock_ocsp_fetch_list(who) /* do nothing */
|
|
#endif /* !THREADS */
|
|
|
|
/**
|
|
* Free the dynamic memory used to store fetch requests
|
|
*/
|
|
static void free_fetch_request(fetch_req_t *req)
|
|
{
|
|
req->distributionPoints->destroy_function(req->distributionPoints, free);
|
|
DESTROY_IF(req->issuer);
|
|
free(req->authKeyID.ptr);
|
|
free(req);
|
|
}
|
|
|
|
#ifdef THREADS
|
|
/**
|
|
* Fetch an ASN.1 blob coded in PEM or DER format from a URL
|
|
*/
|
|
x509crl_t* fetch_crl(char *url)
|
|
{
|
|
x509crl_t *crl;
|
|
chunk_t blob;
|
|
|
|
DBG1(DBG_LIB, " fetching crl from '%s' ...", url);
|
|
if (lib->fetcher->fetch(lib->fetcher, url, &blob, FETCH_END) != SUCCESS)
|
|
{
|
|
DBG1(DBG_LIB, "crl fetching failed");
|
|
return FALSE;
|
|
}
|
|
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL,
|
|
BUILD_BLOB_PEM, blob, BUILD_END);
|
|
free(blob.ptr);
|
|
if (!crl)
|
|
{
|
|
DBG1(DBG_LIB, "crl fetched successfully but data coded in unknown "
|
|
"format");
|
|
}
|
|
return crl;
|
|
}
|
|
|
|
/**
|
|
* Complete a distributionPoint URI with ca information
|
|
*/
|
|
static char* complete_uri(char *distPoint, const char *ldaphost)
|
|
{
|
|
char *symbol = strchr(distPoint, ':');
|
|
|
|
if (symbol)
|
|
{
|
|
int type_len = symbol - distPoint;
|
|
|
|
if (type_len >= 4 && strncasecmp(distPoint, "ldap", 4) == 0)
|
|
{
|
|
char *ptr = symbol + 1;
|
|
int len = strlen(distPoint) - (type_len + 1);
|
|
|
|
if (len > 2 && *ptr++ == '/' && *ptr++ == '/')
|
|
{
|
|
len -= 2;
|
|
symbol = strchr(ptr, '/');
|
|
|
|
if (symbol && symbol - ptr == 0 && ldaphost)
|
|
{
|
|
char uri[BUF_LEN];
|
|
|
|
/* insert the ldaphost into the uri */
|
|
snprintf(uri, BUF_LEN, "%.*s%s%.*s", strlen(distPoint)-len,
|
|
distPoint, ldaphost, len, symbol);
|
|
return strdup(uri);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* default action: copy distributionPoint without change */
|
|
return strdup(distPoint);
|
|
}
|
|
|
|
/**
|
|
* Try to fetch the crls defined by the fetch requests
|
|
*/
|
|
static void fetch_crls(bool cache_crls)
|
|
{
|
|
fetch_req_t *req;
|
|
fetch_req_t **reqp;
|
|
|
|
lock_crl_fetch_list("fetch_crls");
|
|
req = crl_fetch_reqs;
|
|
reqp = &crl_fetch_reqs;
|
|
|
|
while (req != NULL)
|
|
{
|
|
enumerator_t *enumerator;
|
|
char *point;
|
|
bool valid_crl = FALSE;
|
|
const char *ldaphost;
|
|
ca_info_t *ca;
|
|
|
|
lock_ca_info_list("fetch_crls");
|
|
|
|
ca = get_ca_info(req->issuer, req->authKeyID);
|
|
ldaphost = (ca == NULL)? NULL : ca->ldaphost;
|
|
|
|
enumerator = req->distributionPoints->create_enumerator(req->distributionPoints);
|
|
while (enumerator->enumerate(enumerator, &point))
|
|
{
|
|
x509crl_t *crl;
|
|
char *uri;
|
|
|
|
uri = complete_uri(point, ldaphost);
|
|
crl = fetch_crl(uri);
|
|
free(uri);
|
|
|
|
if (crl)
|
|
{
|
|
if (insert_crl(crl, point, cache_crls))
|
|
{
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("we have a valid crl")
|
|
)
|
|
valid_crl = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
unlock_ca_info_list("fetch_crls");
|
|
|
|
if (valid_crl)
|
|
{
|
|
/* delete fetch request */
|
|
fetch_req_t *req_free = req;
|
|
|
|
req = req->next;
|
|
*reqp = req;
|
|
free_fetch_request(req_free);
|
|
}
|
|
else
|
|
{
|
|
/* try again next time */
|
|
req->trials++;
|
|
reqp = &req->next;
|
|
req = req->next;
|
|
}
|
|
}
|
|
unlock_crl_fetch_list("fetch_crls");
|
|
}
|
|
|
|
static void fetch_ocsp_status(ocsp_location_t* location)
|
|
{
|
|
chunk_t request = build_ocsp_request(location);
|
|
chunk_t response = chunk_empty;
|
|
|
|
DBG1(DBG_LIB, " requesting ocsp status from '%s' ...", location->uri);
|
|
if (lib->fetcher->fetch(lib->fetcher, location->uri, &response,
|
|
FETCH_REQUEST_DATA, request,
|
|
FETCH_REQUEST_TYPE, "application/ocsp-request",
|
|
FETCH_END) == SUCCESS)
|
|
{
|
|
parse_ocsp(location, response);
|
|
}
|
|
else
|
|
{
|
|
DBG1(DBG_LIB, "ocsp request to %s failed", location->uri);
|
|
}
|
|
|
|
free(request.ptr);
|
|
chunk_free(&location->nonce);
|
|
|
|
/* increment the trial counter of the unresolved fetch requests */
|
|
{
|
|
ocsp_certinfo_t *certinfo = location->certinfo;
|
|
|
|
while (certinfo != NULL)
|
|
{
|
|
certinfo->trials++;
|
|
certinfo = certinfo->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Try to fetch the necessary ocsp information
|
|
*/
|
|
static void fetch_ocsp(void)
|
|
{
|
|
ocsp_location_t *location;
|
|
|
|
lock_ocsp_fetch_list("fetch_ocsp");
|
|
location = ocsp_fetch_reqs;
|
|
|
|
/* fetch the ocps status for all locations */
|
|
while (location != NULL)
|
|
{
|
|
if (location->certinfo != NULL)
|
|
{
|
|
fetch_ocsp_status(location);
|
|
}
|
|
location = location->next;
|
|
}
|
|
|
|
unlock_ocsp_fetch_list("fetch_ocsp");
|
|
}
|
|
|
|
static void* fetch_thread(void *arg)
|
|
{
|
|
struct timespec wait_interval;
|
|
|
|
/* the fetching thread is only cancellable while waiting for new events */
|
|
thread_cancelability(FALSE);
|
|
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("fetch thread started")
|
|
)
|
|
|
|
pthread_mutex_lock(&fetch_wake_mutex);
|
|
|
|
while(1)
|
|
{
|
|
int status;
|
|
|
|
wait_interval.tv_nsec = 0;
|
|
wait_interval.tv_sec = time(NULL) + crl_check_interval;
|
|
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("next regular crl check in %ld seconds", crl_check_interval)
|
|
)
|
|
|
|
thread_cancelability(TRUE);
|
|
status = pthread_cond_timedwait(&fetch_wake_cond, &fetch_wake_mutex
|
|
, &wait_interval);
|
|
thread_cancelability(FALSE);
|
|
|
|
if (status == ETIMEDOUT)
|
|
{
|
|
DBG(DBG_CONTROL,
|
|
DBG_log(" ");
|
|
DBG_log("*time to check crls and the ocsp cache")
|
|
)
|
|
check_ocsp();
|
|
check_crls();
|
|
}
|
|
else
|
|
{
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("fetch thread was woken up")
|
|
)
|
|
}
|
|
fetch_ocsp();
|
|
fetch_crls(cache_crls);
|
|
}
|
|
return NULL;
|
|
}
|
|
#endif /* THREADS*/
|
|
|
|
/**
|
|
* Initializes curl and starts the fetching thread
|
|
*/
|
|
void fetch_initialize(void)
|
|
{
|
|
if (crl_check_interval > 0)
|
|
{
|
|
#ifdef THREADS
|
|
thread = thread_create((thread_main_t)fetch_thread, NULL);
|
|
if (thread == NULL)
|
|
{
|
|
plog("fetching thread could not be started");
|
|
}
|
|
#else /* !THREADS */
|
|
plog("warning: not compiled with pthread support");
|
|
#endif /* !THREADS */
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Terminates the fetching thread
|
|
*/
|
|
void fetch_finalize(void)
|
|
{
|
|
if (crl_check_interval > 0)
|
|
{
|
|
#ifdef THREADS
|
|
if (thread)
|
|
{
|
|
thread->cancel(thread);
|
|
thread->join(thread);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void free_crl_fetch(void)
|
|
{
|
|
lock_crl_fetch_list("free_crl_fetch");
|
|
|
|
while (crl_fetch_reqs != NULL)
|
|
{
|
|
fetch_req_t *req = crl_fetch_reqs;
|
|
crl_fetch_reqs = req->next;
|
|
free_fetch_request(req);
|
|
}
|
|
|
|
unlock_crl_fetch_list("free_crl_fetch");
|
|
}
|
|
|
|
/**
|
|
* Free the chained list of ocsp requests
|
|
*/
|
|
void free_ocsp_fetch(void)
|
|
{
|
|
lock_ocsp_fetch_list("free_ocsp_fetch");
|
|
free_ocsp_locations(&ocsp_fetch_reqs);
|
|
unlock_ocsp_fetch_list("free_ocsp_fetch");
|
|
}
|
|
|
|
|
|
/**
|
|
* Add an additional distribution point
|
|
*/
|
|
void add_distribution_point(linked_list_t *points, char *new_point)
|
|
{
|
|
char *point;
|
|
bool add = TRUE;
|
|
enumerator_t *enumerator;
|
|
|
|
if (new_point == NULL || *new_point == '\0')
|
|
{
|
|
return;
|
|
}
|
|
|
|
enumerator = points->create_enumerator(points);
|
|
while (enumerator->enumerate(enumerator, &point))
|
|
{
|
|
if (streq(point, new_point))
|
|
{
|
|
add = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
|
|
if (add)
|
|
{
|
|
points->insert_last(points, strdup(new_point));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add additional distribution points
|
|
*/
|
|
void add_distribution_points(linked_list_t *points, linked_list_t *new_points)
|
|
{
|
|
char *new_point;
|
|
enumerator_t *enumerator;
|
|
|
|
enumerator = new_points->create_enumerator(new_points);
|
|
while (enumerator->enumerate(enumerator, &new_point))
|
|
{
|
|
bool add = TRUE;
|
|
char *point;
|
|
enumerator_t *enumerator;
|
|
|
|
enumerator = points->create_enumerator(points);
|
|
while (enumerator->enumerate(enumerator, &point))
|
|
{
|
|
if (streq(point, new_point))
|
|
{
|
|
add = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
|
|
if (add)
|
|
{
|
|
points->insert_last(points, strdup(new_point));
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
}
|
|
|
|
fetch_req_t* build_crl_fetch_request(identification_t *issuer,
|
|
chunk_t authKeyID,
|
|
linked_list_t *distributionPoints)
|
|
{
|
|
char *point;
|
|
enumerator_t *enumerator;
|
|
fetch_req_t *req = malloc_thing(fetch_req_t);
|
|
|
|
memset(req, 0, sizeof(fetch_req_t));
|
|
req->distributionPoints = linked_list_create();
|
|
|
|
/* clone fields */
|
|
req->issuer = issuer->clone(issuer);
|
|
req->authKeyID = chunk_clone(authKeyID);
|
|
|
|
/* copy distribution points */
|
|
enumerator = distributionPoints->create_enumerator(distributionPoints);
|
|
while (enumerator->enumerate(enumerator, &point))
|
|
{
|
|
req->distributionPoints->insert_last(req->distributionPoints,
|
|
strdup(point));
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
|
|
return req;
|
|
}
|
|
|
|
/**
|
|
* Add a crl fetch request to the chained list
|
|
*/
|
|
void add_crl_fetch_request(fetch_req_t *req)
|
|
{
|
|
fetch_req_t *r;
|
|
|
|
lock_crl_fetch_list("add_crl_fetch_request");
|
|
r = crl_fetch_reqs;
|
|
|
|
while (r != NULL)
|
|
{
|
|
if (req->authKeyID.ptr ? same_keyid(req->authKeyID, r->authKeyID) :
|
|
req->issuer->equals(req->issuer, r->issuer))
|
|
{
|
|
/* there is already a fetch request */
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("crl fetch request already exists")
|
|
)
|
|
|
|
/* there might be new distribution points */
|
|
add_distribution_points(r->distributionPoints,
|
|
req->distributionPoints);
|
|
|
|
unlock_crl_fetch_list("add_crl_fetch_request");
|
|
free_fetch_request(req);
|
|
return;
|
|
}
|
|
r = r->next;
|
|
}
|
|
|
|
/* insert new fetch request at the head of the queue */
|
|
req->next = crl_fetch_reqs;
|
|
crl_fetch_reqs = req;
|
|
|
|
DBG(DBG_CONTROL,
|
|
DBG_log("crl fetch request added")
|
|
)
|
|
unlock_crl_fetch_list("add_crl_fetch_request");
|
|
}
|
|
|
|
/**
|
|
* Add an ocsp fetch request to the chained list
|
|
*/
|
|
void add_ocsp_fetch_request(ocsp_location_t *location, chunk_t serialNumber)
|
|
{
|
|
ocsp_certinfo_t certinfo;
|
|
|
|
certinfo.serialNumber = serialNumber;
|
|
|
|
lock_ocsp_fetch_list("add_ocsp_fetch_request");
|
|
add_certinfo(location, &certinfo, &ocsp_fetch_reqs, TRUE);
|
|
unlock_ocsp_fetch_list("add_ocsp_fetch_request");
|
|
}
|
|
|
|
/**
|
|
* List all distribution points
|
|
*/
|
|
void list_distribution_points(linked_list_t *distributionPoints)
|
|
{
|
|
char *point;
|
|
bool first_point = TRUE;
|
|
enumerator_t *enumerator;
|
|
|
|
enumerator = distributionPoints->create_enumerator(distributionPoints);
|
|
while (enumerator->enumerate(enumerator, &point))
|
|
{
|
|
whack_log(RC_COMMENT, " %s '%s'",
|
|
(first_point)? "distPts: " : " ", point);
|
|
first_point = FALSE;
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
}
|
|
|
|
/**
|
|
* List all fetch requests in the chained list
|
|
*/
|
|
void list_crl_fetch_requests(bool utc)
|
|
{
|
|
fetch_req_t *req;
|
|
|
|
lock_crl_fetch_list("list_crl_fetch_requests");
|
|
req = crl_fetch_reqs;
|
|
|
|
if (req != NULL)
|
|
{
|
|
whack_log(RC_COMMENT, " ");
|
|
whack_log(RC_COMMENT, "List of CRL Fetch Requests:");
|
|
}
|
|
|
|
while (req != NULL)
|
|
{
|
|
whack_log(RC_COMMENT, " ");
|
|
whack_log(RC_COMMENT, " trials: %d", req->trials);
|
|
whack_log(RC_COMMENT, " issuer: \"%Y\"", req->issuer);
|
|
if (req->authKeyID.ptr)
|
|
{
|
|
whack_log(RC_COMMENT, " authkey: %#B", &req->authKeyID);
|
|
}
|
|
list_distribution_points(req->distributionPoints);
|
|
req = req->next;
|
|
}
|
|
unlock_crl_fetch_list("list_crl_fetch_requests");
|
|
}
|
|
|
|
void list_ocsp_fetch_requests(bool utc)
|
|
{
|
|
lock_ocsp_fetch_list("list_ocsp_fetch_requests");
|
|
list_ocsp_locations(ocsp_fetch_reqs, TRUE, utc, FALSE);
|
|
unlock_ocsp_fetch_list("list_ocsp_fetch_requests");
|
|
|
|
}
|