/**
* 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
*/
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;
}
/* 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;
typedef struct ca_info_t ca_info_t;
#include <library.h>
+#include <chunk.h>
#include "x509.h"
*/
struct ca_info_t {
+ /**
+ * @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
+ * @return TRUE if a match is found
+ */
+ 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 crl uri string to be added
+ * @param uri crl uri to be added
*/
- void (*add_crluri) (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 string to be added
+ * @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 (*add_ocspuri) (ca_info_t *this, const char* uri);
+ void (*release_info) (ca_info_t *this);
/**
* @brief Destroys a ca info record