full support of ca info records

This commit is contained in:
Andreas Steffen
2007-02-24 23:18:31 +00:00
parent 83fbaa1ff0
commit b3e4211fc3
2 changed files with 112 additions and 23 deletions
@@ -126,7 +126,7 @@ struct credential_store_t {
x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid);
/**
* @brief Returns the ca certificate of a specific subject distinguished name.
* @brief Returns the issuer certificate of a given certificate.
*
* @param this calling object
* @param id certificate for which issuer cert is required
@@ -166,10 +166,20 @@ struct credential_store_t {
* @brief If a ca info record does not already exists in the credential store then add it.
*
* @param this calling object
* @param cert ca info record to be added
* @return pointer to the added or already existing ca info record
* @param ca_info ca info record to be added
*/
ca_info_t* (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
void (*add_ca_info) (credential_store_t *this, ca_info_t *ca_info);
/**
* @brief Release a ca info record with a given name.
*
* @param this calling object
* @param name name of the ca info record to be released
* @return
* - SUCCESS, or
* - NOT_FOUND
*/
status_t (*release_ca_info) (credential_store_t *this, const char *name);
/**
* @brief Create an iterator over all end certificates.
@@ -126,6 +126,11 @@ struct private_local_credential_store_t {
*/
linked_list_t *ca_infos;
/**
* mutex controlling the access to the ca_infos linked list
*/
pthread_mutex_t ca_infos_mutex;
/**
* list of X.509 CRLs
*/
@@ -473,7 +478,7 @@ static cert_status_t verify_by_ocsp(private_local_credential_store_t* this,
/**
* Find an exact copy of a certificate in a linked list
*/
static x509_t* find_certificate_copy(linked_list_t *certs, x509_t *cert)
static x509_t* find_certificate(linked_list_t *certs, x509_t *cert)
{
x509_t *found_cert = NULL, *current_cert;
@@ -501,7 +506,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
time_t until = UNDEFINED_TIME;
x509_t *end_cert = cert;
x509_t *cert_copy = find_certificate_copy(this->certs, end_cert);
x509_t *cert_copy = find_certificate(this->certs, end_cert);
*found = (cert_copy != NULL);
if (*found)
@@ -656,7 +661,7 @@ static bool verify(private_local_credential_store_t *this, x509_t *cert, bool *f
*/
static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
{
x509_t *found_cert = find_certificate_copy(certs, cert);
x509_t *found_cert = find_certificate(certs, cert);
if (found_cert)
{
@@ -670,12 +675,86 @@ static x509_t* add_certificate(linked_list_t *certs, x509_t *cert)
}
}
/**
* Add a unique ca info record to a linked list
*/
static void add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
{
ca_info_t *current_ca_info;
ca_info_t *found_ca_info = NULL;
iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
while (iterator->iterate(iterator, (void**)&current_ca_info))
{
if (current_ca_info->equals(current_ca_info, ca_info))
{
found_ca_info = current_ca_info;
break;
}
}
if (found_ca_info)
{
current_ca_info->add_info(current_ca_info, ca_info);
ca_info->destroy(ca_info);
}
else
{
this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
}
iterator->destroy(iterator);
}
/**
* Release ca info record of a given name
*/
static status_t release_ca_info(private_local_credential_store_t *this, const char *name)
{
status_t status = NOT_FOUND;
ca_info_t *ca_info;
iterator_t *iterator = this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
while (iterator->iterate(iterator, (void**)&ca_info))
{
if (ca_info->equals_name(ca_info, name))
{
ca_info->release_info(ca_info);
status = SUCCESS;
break;
}
}
iterator->destroy(iterator);
}
/**
* Implements local_credential_store_t.add_end_certificate
*/
static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
{
return add_certificate(this->certs, cert);
x509_t *ret_cert = add_certificate(this->certs, cert);
if (ret_cert == cert)
{
x509_t *issuer_cert = get_issuer_certificate(this, cert);
if (issuer_cert)
{
ca_info_t *ca_info = ca_info_create(NULL, issuer_cert);
iterator_t *iterator = cert->create_crluri_iterator(cert);
identification_t *uri;
while (iterator->iterate(iterator, (void**)&uri))
{
ca_info->add_crluri(ca_info, uri->get_encoding(uri));
}
iterator->destroy(iterator);
add_ca_info(this, ca_info);
}
}
return ret_cert;
}
/**
@@ -683,16 +762,7 @@ static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_
*/
static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t *cert)
{
return add_certificate(this->ca_certs, cert);
}
/**
* Add a unique ca info record to a linked list
*/
static ca_info_t* add_ca_info(private_local_credential_store_t *this, ca_info_t *ca_info)
{
this->ca_infos->insert_last(this->ca_infos, (void*)ca_info);
return ca_info;
add_certificate(this->ca_certs, cert);
}
/**
@@ -716,7 +786,7 @@ static iterator_t* create_cacert_iterator(private_local_credential_store_t *this
*/
static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this)
{
return this->ca_infos->create_iterator(this->ca_infos, TRUE);
return this->ca_infos->create_iterator_locked(this->ca_infos, &(this->ca_infos_mutex));
}
/**
@@ -735,7 +805,6 @@ static void load_ca_certificates(private_local_credential_store_t *this)
struct dirent* entry;
struct stat stb;
DIR* dir;
x509_t *cert;
DBG1(DBG_CFG, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR);
@@ -759,7 +828,8 @@ static void load_ca_certificates(private_local_credential_store_t *this)
/* try to parse all regular files */
if (stb.st_mode & S_IFREG)
{
cert = x509_create_from_file(file, "ca certificate");
x509_t *cert = x509_create_from_file(file, "ca certificate");
if (cert)
{
err_t ugh = cert->is_valid(cert, NULL);
@@ -770,7 +840,14 @@ static void load_ca_certificates(private_local_credential_store_t *this)
}
if (cert->is_ca(cert))
{
cert = add_certificate(this->ca_certs, cert);
x509_t *ret_cert = add_certificate(this->ca_certs, cert);
if (ret_cert == cert)
{
ca_info_t *ca_info = ca_info_create(NULL, cert);
add_ca_info(this, ca_info);
}
}
else
{
@@ -1151,7 +1228,8 @@ local_credential_store_t * local_credential_store_create(bool strict)
this->public.credential_store.verify = (bool (*) (credential_store_t*,x509_t*,bool*))verify;
this->public.credential_store.add_end_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_end_certificate;
this->public.credential_store.add_ca_certificate = (x509_t* (*) (credential_store_t*,x509_t*))add_ca_certificate;
this->public.credential_store.add_ca_info = (ca_info_t* (*) (credential_store_t*,ca_info_t*))add_ca_info;
this->public.credential_store.add_ca_info = (void (*) (credential_store_t*,ca_info_t*))add_ca_info;
this->public.credential_store.release_ca_info = (status_t (*) (credential_store_t*,const char*))release_ca_info;
this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator;
this->public.credential_store.create_cacert_iterator = (iterator_t* (*) (credential_store_t*))create_cacert_iterator;
this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator;
@@ -1163,6 +1241,7 @@ local_credential_store_t * local_credential_store_create(bool strict)
/* initialize mutexes */
pthread_mutex_init(&(this->crls_mutex), NULL);
pthread_mutex_init(&(this->ca_infos_mutex), NULL);
/* private variables */
this->shared_keys = linked_list_create();