full support of ca info records
This commit is contained in:
@@ -126,7 +126,7 @@ struct credential_store_t {
|
|||||||
x509_t* (*get_ca_certificate_by_keyid) (credential_store_t *this, chunk_t keyid);
|
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 this calling object
|
||||||
* @param id certificate for which issuer cert is required
|
* @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.
|
* @brief If a ca info record does not already exists in the credential store then add it.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
* @param cert ca info record to be added
|
* @param ca_info ca info record to be added
|
||||||
* @return pointer to the added or already existing ca info record
|
|
||||||
*/
|
*/
|
||||||
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.
|
* @brief Create an iterator over all end certificates.
|
||||||
|
|||||||
@@ -126,6 +126,11 @@ struct private_local_credential_store_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *ca_infos;
|
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
|
* 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
|
* 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;
|
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;
|
time_t until = UNDEFINED_TIME;
|
||||||
|
|
||||||
x509_t *end_cert = cert;
|
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);
|
*found = (cert_copy != NULL);
|
||||||
if (*found)
|
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)
|
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)
|
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**)¤t_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
|
* Implements local_credential_store_t.add_end_certificate
|
||||||
*/
|
*/
|
||||||
static x509_t* add_end_certificate(private_local_credential_store_t *this, x509_t *cert)
|
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)
|
static x509_t* add_ca_certificate(private_local_credential_store_t *this, x509_t *cert)
|
||||||
{
|
{
|
||||||
return add_certificate(this->ca_certs, cert);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -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)
|
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 dirent* entry;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
x509_t *cert;
|
|
||||||
|
|
||||||
DBG1(DBG_CFG, "loading ca certificates from '%s/'", CA_CERTIFICATE_DIR);
|
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 */
|
/* try to parse all regular files */
|
||||||
if (stb.st_mode & S_IFREG)
|
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)
|
if (cert)
|
||||||
{
|
{
|
||||||
err_t ugh = cert->is_valid(cert, NULL);
|
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))
|
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
|
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.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_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_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_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_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;
|
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 */
|
/* initialize mutexes */
|
||||||
pthread_mutex_init(&(this->crls_mutex), NULL);
|
pthread_mutex_init(&(this->crls_mutex), NULL);
|
||||||
|
pthread_mutex_init(&(this->ca_infos_mutex), NULL);
|
||||||
|
|
||||||
/* private variables */
|
/* private variables */
|
||||||
this->shared_keys = linked_list_create();
|
this->shared_keys = linked_list_create();
|
||||||
|
|||||||
Reference in New Issue
Block a user