full support of ca info records
This commit is contained in:
+177
-25
@@ -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**)¤t_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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user