full support of ca info records

This commit is contained in:
Andreas Steffen
2007-02-24 23:21:57 +00:00
parent e3c0ece8c8
commit db56de5bf7
2 changed files with 217 additions and 30 deletions
+177 -25
View File
@@ -56,54 +56,167 @@ struct private_ca_info_t {
/**
* Distinguished Name of the CA
*/
x509_t *cacert;
const x509_t *cacert;
/**
* List of crlDistributionPoints
* List of crl URIs
*/
linked_list_t *crlURIs;
/**
* List of ocspAccessPoints
* List of ocsp URIs
*/
linked_list_t *ocspURIs;
};
/**
* Implements ca_info_t.equals
*/
static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
{
return chunk_equals(this->cacert->get_keyid(this->cacert),
that->cacert->get_keyid(that->cacert));
}
/**
* Implements ca_info_t.equals_name
*/
static bool equals_name(const private_ca_info_t *this, const char *name)
{
return this->name != NULL && streq(this->name, name);
}
/**
* Find an exact copy of an identification in a linked list
*/
static identification_t* find_identification(linked_list_t *list, identification_t *id)
{
identification_t *found_id = NULL, *current_id;
iterator_t *iterator = list->create_iterator(list, TRUE);
while (iterator->iterate(iterator, (void**)&current_id))
{
if (id->equals(id, current_id))
{
found_id = current_id;
break;
}
}
iterator->destroy(iterator);
return found_id;
}
/**
* Add a unique identification to a linked list
*/
static identification_t *add_identification(linked_list_t *list, identification_t *id)
{
identification_t *found_id = find_identification(list, id);
if (found_id)
{
id->destroy(id);
return found_id;
}
else
{
list->insert_last(list, (void*)id);
return id;
}
}
/**
* Implements ca_info_t.add_crluri
*/
static void add_crluri(private_ca_info_t *this, const char* uri)
static void add_crluri(private_ca_info_t *this, chunk_t uri)
{
if (uri == NULL)
if (uri.len < 6 ||
(strncasecmp(uri.ptr, "http", 4) != 0 &&
strncasecmp(uri.ptr, "ldap", 4) != 0 &&
strncasecmp(uri.ptr, "file", 4) != 0 &&
strncasecmp(uri.ptr, "ftp", 3) != 0))
{
DBG1(" invalid crl uri '%#B'", uri);
return;
}
if (strncasecmp(uri, "http", 4) != 0
&& strncasecmp(uri, "ldap", 4) != 0
&& strncasecmp(uri, "file", 4) != 0
&& strncasecmp(uri, "ftp", 3) != 0)
else
{
DBG1(" invalid crl uri '%s'", uri);
return;
identification_t *crlURI = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
add_identification(this->crlURIs, crlURI);
}
}
/**
* Implements ca_info_t.add_ocspuri
*/
static void add_ocspuri(private_ca_info_t *this, const char* uri)
static void add_ocspuri(private_ca_info_t *this, chunk_t uri)
{
if (uri == NULL)
if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0)
{
DBG1(" invalid ocsp uri '%.*s'", uri.len, uri.ptr);
return;
}
if (strncasecmp(uri, "http", 4) != 0)
else
{
DBG1(" invalid ocsp uri '%s'", uri);
return;
identification_t *ocspURI = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
add_identification(this->ocspURIs, ocspURI);
}
}
/**
* Implements ca_info_t.add_info
*/
void add_info (private_ca_info_t *this, const private_ca_info_t *that)
{
if (this->name == NULL && that->name != NULL)
{
this->name = strdup(that->name);
}
{
identification_t *uri;
iterator_t *iterator = that->crlURIs->create_iterator(that->crlURIs, TRUE);
while (iterator->iterate(iterator, (void**)&uri))
{
add_crluri(this, uri->get_encoding(uri));
}
iterator->destroy(iterator);
}
{
identification_t *uri;
iterator_t *iterator = that->ocspURIs->create_iterator(that->ocspURIs, TRUE);
while (iterator->iterate(iterator, (void**)&uri))
{
add_ocspuri(this, uri->get_encoding(uri));
}
iterator->destroy(iterator);
}
}
/**
* Implements ca_info_t.release_info
*/
static void release_info(private_ca_info_t *this)
{
this->crlURIs->destroy_offset(this->crlURIs,
offsetof(identification_t, destroy));
this->crlURIs = linked_list_create();
this->ocspURIs->destroy_offset(this->ocspURIs,
offsetof(identification_t, destroy));
this->ocspURIs = linked_list_create();
free(this->name);
this->name = NULL;
}
/**
* Implements ca_info_t.destroy
*/
@@ -126,27 +239,62 @@ static int print(FILE *stream, const struct printf_info *info,
private_ca_info_t *this = *((private_ca_info_t**)(args[0]));
bool utc = TRUE;
int written = 0;
x509_t *cacert;
const x509_t *cacert;
chunk_t keyid;
if (info->alt)
{
utc = *((bool*)args[1]);
}
if (this == NULL)
{
return fprintf(stream, "(null)");
}
written += fprintf(stream, "%#T, \"%s\"\n", &this->installed, utc, this->name);
written += fprintf(stream, "%#T", &this->installed, utc);
if (this->name)
{
written += fprintf(stream, ", \"%s\"\n", this->name);
}
else
{
written += fprintf(stream, "\n");
}
cacert = this->cacert;
written += fprintf(stream, " authname: '%D'\n", cacert->get_subject(cacert));
keyid = cacert->get_keyid(cacert);
written += fprintf(stream, " keyid: %#B\n", &keyid);
{
chunk_t keyid = cacert->get_keyid(cacert);
written += fprintf(stream, " keyid: %#B\n", &keyid);
}
{
identification_t *crlURI;
iterator_t *iterator = this->crlURIs->create_iterator(this->crlURIs, TRUE);
bool first = TRUE;
while (iterator->iterate(iterator, (void**)&crlURI))
{
written += fprintf(stream, " %s '%D'\n",
first? "crluris:":" ", crlURI);
first = FALSE;
}
iterator->destroy(iterator);
}
{
identification_t *ocspURI;
iterator_t *iterator = this->ocspURIs->create_iterator(this->ocspURIs, TRUE);
bool first = TRUE;
while (iterator->iterate(iterator, (void**)&ocspURI))
{
written += fprintf(stream, " %s '%D'\n",
first? "ocspuris:":" ", ocspURI);
first = FALSE;
}
iterator->destroy(iterator);
}
return written;
}
@@ -167,14 +315,18 @@ ca_info_t *ca_info_create(const char *name, const x509_t *cacert)
/* initialize */
this->installed = time(NULL);
this->name = strdup(name);
this->name = (name == NULL)? NULL:strdup(name);
this->cacert = cacert;
this->crlURIs = linked_list_create();
this->ocspURIs = linked_list_create();
/* public functions */
this->public.add_crluri = (void (*) (ca_info_t*,const char*))add_crluri;
this->public.add_ocspuri = (void (*) (ca_info_t*,const char*))add_ocspuri;
this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals;
this->public.equals_name = (bool (*) (const ca_info_t*,const char*))equals_name;
this->public.add_info = (void (*) (ca_info_t*,ca_info_t*))add_info;
this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
this->public.release_info = (void (*) (ca_info_t*))release_info;
this->public.destroy = (void (*) (ca_info_t*))destroy;
return &this->public;
+40 -5
View File
@@ -26,6 +26,7 @@
typedef struct ca_info_t ca_info_t;
#include <library.h>
#include <chunk.h>
#include "x509.h"
@@ -40,20 +41,54 @@ typedef struct ca_info_t ca_info_t;
struct ca_info_t {
/**
* @brief Adds a CRL URI to a list
* @brief Compare two ca info records
*
* Comparison is doen via the keyid of the ca certificate
*
* @param this first ca info object
* @param that second ca info objct
* @return TRUE if a match is found
*/
bool (*equals) (const ca_info_t *this, const ca_info_t* that);
/**
* @brief Checks if the ca info record has the same name
*
* @param this ca info object
* @param uri crl uri string to be added
* @return TRUE if a match is found
*/
void (*add_crluri) (ca_info_t *this, const char* uri);
bool (*equals_name) (const ca_info_t *this, const char *name);
/**
* @brief Merges info from a secondary ca info object
*
* @param this primary ca info object
* @param that secondary ca info object
*/
void (*add_info) (ca_info_t *this, const ca_info_t *that);
/**
* @brief Adds a CRL URI to a list
*
* @param this ca info object
* @param uri ocsp uri string to be added
* @param uri crl uri to be added
*/
void (*add_ocspuri) (ca_info_t *this, const char* uri);
void (*add_crluri) (ca_info_t *this, chunk_t uri);
/**
* @brief Adds a CRL URI to a list
*
* @param this ca info object
* @param uri ocsp uri to be added
*/
void (*add_ocspuri) (ca_info_t *this, chunk_t uri);
/**
* @brief Releases the name and URIs of ca info record
*
* @param this ca info to release
*/
void (*release_info) (ca_info_t *this);
/**
* @brief Destroys a ca info record