From: Andreas Steffen Date: Sat, 24 Feb 2007 23:21:57 +0000 (-0000) Subject: full support of ca info records X-Git-Tag: 4.0.7~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db56de5bf7fad32c86f277a7af286296f3db6303;p=thirdparty%2Fstrongswan.git full support of ca info records --- diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c index d7e46f0c84..c3f707fb0b 100644 --- a/src/libstrongswan/crypto/ca.c +++ b/src/libstrongswan/crypto/ca.c @@ -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; diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h index deff8305c6..8b1bd3d717 100644 --- a/src/libstrongswan/crypto/ca.h +++ b/src/libstrongswan/crypto/ca.h @@ -26,6 +26,7 @@ typedef struct ca_info_t ca_info_t; #include +#include #include "x509.h" @@ -39,21 +40,55 @@ typedef struct ca_info_t ca_info_t; */ 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