From f51d505e5eff07e6de26fb0a655bd0b12546b192 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Tue, 7 Aug 2007 20:32:11 +0000 Subject: [PATCH] implemented listing of attribute certificates --- .../credentials/local_credential_store.c | 34 ++++++++- .../control/interfaces/stroke_interface.c | 18 +++++ src/libstrongswan/credential_store.h | 8 ++ src/libstrongswan/crypto/ac.c | 74 ++++++++++++++++++- src/libstrongswan/crypto/ac.h | 9 +++ 5 files changed, 138 insertions(+), 5 deletions(-) diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c index 649fcbcfb..ce18c670e 100644 --- a/src/charon/config/credentials/local_credential_store.c +++ b/src/charon/config/credentials/local_credential_store.c @@ -171,6 +171,16 @@ struct private_local_credential_store_t { * list of X.509 CA information records */ linked_list_t *ca_infos; + + /** + * list of X.509 attribute certificates + */ + linked_list_t *acerts; + + /** + * mutex controls access to the linked list of attribute certificates + */ + pthread_mutex_t acerts_mutex; }; @@ -937,6 +947,14 @@ static iterator_t* create_cainfo_iterator(private_local_credential_store_t *this return this->ca_infos->create_iterator(this->ca_infos, TRUE); } +/** + * Implements local_credential_store_t.create_acert_iterator + */ +static iterator_t* create_acert_iterator(private_local_credential_store_t *this) +{ + return this->acerts->create_iterator_locked(this->acerts, &this->acerts_mutex); +} + /** * Implements local_credential_store_t.load_auth_certificates */ @@ -1053,7 +1071,10 @@ static void load_aa_certificates(private_local_credential_store_t *this) */ static void add_attr_certificate(private_local_credential_store_t *this, x509ac_t *cert) { - /* TODO add a new attribute certificate to the linked list */ + /* TODO replace stale attribute certificates by fresh ones */ + pthread_mutex_lock(&(this->acerts_mutex)); + this->acerts->insert_last(this->acerts, (void*)cert); + pthread_mutex_unlock(&(this->acerts_mutex)); } /** @@ -1447,6 +1468,7 @@ static void destroy(private_local_credential_store_t *this) this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy)); this->auth_certs->destroy_offset(this->auth_certs, offsetof(x509_t, destroy)); this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy)); + this->acerts->destroy_offset(this->certs, offsetof(x509ac_t, destroy)); this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy)); this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy); this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy); @@ -1459,7 +1481,8 @@ static void destroy(private_local_credential_store_t *this) local_credential_store_t * local_credential_store_create(void) { private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t); - + + /* public functions */ this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key; this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key; this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key; @@ -1479,6 +1502,7 @@ local_credential_store_t * local_credential_store_create(void) this->public.credential_store.create_cert_iterator = (iterator_t* (*) (credential_store_t*))create_cert_iterator; this->public.credential_store.create_auth_cert_iterator = (iterator_t* (*) (credential_store_t*))create_auth_cert_iterator; this->public.credential_store.create_cainfo_iterator = (iterator_t* (*) (credential_store_t*))create_cainfo_iterator; + this->public.credential_store.create_acert_iterator = (iterator_t* (*) (credential_store_t*))create_acert_iterator; this->public.credential_store.load_ca_certificates = (void (*) (credential_store_t*))load_ca_certificates; this->public.credential_store.load_aa_certificates = (void (*) (credential_store_t*))load_aa_certificates; this->public.credential_store.load_attr_certificates = (void (*) (credential_store_t*))load_attr_certificates; @@ -1486,7 +1510,10 @@ local_credential_store_t * local_credential_store_create(void) this->public.credential_store.load_crls = (void (*) (credential_store_t*))load_crls; this->public.credential_store.load_secrets = (void (*) (credential_store_t*))load_secrets; this->public.credential_store.destroy = (void (*) (credential_store_t*))destroy; - + + /* initialize the mutex */ + pthread_mutex_init(&(this->acerts_mutex), NULL); + /* private variables */ this->shared_keys = linked_list_create(); this->eap_keys = linked_list_create(); @@ -1494,6 +1521,7 @@ local_credential_store_t * local_credential_store_create(void) this->certs = linked_list_create(); this->auth_certs = linked_list_create(); this->ca_infos = linked_list_create(); + this->acerts = linked_list_create(); return (&this->public); } diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c index 71d444491..720038238 100755 --- a/src/charon/control/interfaces/stroke_interface.c +++ b/src/charon/control/interfaces/stroke_interface.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1380,6 +1381,23 @@ static void stroke_list(stroke_msg_t *msg, FILE *out) { list_auth_certificates(AUTH_AA, "AA", msg->list.utc, out); } + if (msg->list.flags & LIST_ACERTS) + { + x509ac_t *cert; + + iterator = charon->credentials->create_acert_iterator(charon->credentials); + if (iterator->get_count(iterator)) + { + fprintf(out, "\n"); + fprintf(out, "List of X.509 Attribute Certificates:\n"); + fprintf(out, "\n"); + } + while (iterator->iterate(iterator, (void**)&cert)) + { + cert->list(cert, out, msg->list.utc); + } + iterator->destroy(iterator); + } if (msg->list.flags & LIST_CAINFOS) { ca_info_t *ca_info; diff --git a/src/libstrongswan/credential_store.h b/src/libstrongswan/credential_store.h index dcbe43f52..29381cd47 100755 --- a/src/libstrongswan/credential_store.h +++ b/src/libstrongswan/credential_store.h @@ -239,6 +239,14 @@ struct credential_store_t { */ iterator_t* (*create_cainfo_iterator) (credential_store_t *this); + /** + * @brief Create an iterator over all attribute certificates. + * + * @param this calling object + * @return iterator + */ + iterator_t* (*create_acert_iterator) (credential_store_t *this); + /** * @brief Loads ca certificates from a default directory. * diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c index 47605e9e1..29431ad69 100644 --- a/src/libstrongswan/crypto/ac.c +++ b/src/libstrongswan/crypto/ac.c @@ -21,15 +21,19 @@ * for more details. */ +#include +#include + #include #include #include #include #include - #include "ac.h" +#define ACERT_WARNING_INTERVAL 1 /* day */ + typedef struct private_x509ac_t private_x509ac_t; /** @@ -603,7 +607,72 @@ static bool parse_certificate(chunk_t blob, private_x509ac_t *this) objectID++; } this->installed = time(NULL); - return FALSE; + return TRUE; +} + +/** + * Implementation of x509ac_t.list. + */ +static void list(private_x509ac_t *this, FILE *out, bool utc) +{ + time_t now = time(NULL); + + fprintf(out, "%#T\n", &this->installed, utc); + + if (this->entityName) + { + fprintf(out, " holder: '%D'\n", this->entityName); + } + if (this->holderIssuer) + { + fprintf(out, " hissuer: '%D'\n", this->holderIssuer); + } + if (this->holderSerial.ptr) + { + fprintf(out, " hserial: %#B\n", &this->holderSerial); + } +/* if (ac->groups != NULL) + { + format_groups(ac->groups, buf, BUF_LEN); + whack_log(RC_COMMENT, " groups: %s", buf); + } +*/ + fprintf(out, " issuer: '%D'\n", this->issuerName); + fprintf(out, " serial: %#B\n", &this->serialNumber); + + fprintf(out, " validity: not before %#T, ", &this->notBefore, utc); + if (now < this->notBefore) + { + fprintf(out, "not valid yet (valid in %V)\n", &now, &this->notBefore); + } + else + { + fprintf(out, "ok\n"); + } + + fprintf(out, " not after %#T, ", &this->notAfter, utc); + if (now > this->notAfter) + { + fprintf(out, "expired (%V ago)\n", &now, &this->notAfter); + } + else + { + fprintf(out, "ok"); + if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24) + { + fprintf(out, " (expires in %V)", &now, &this->notAfter); + } + fprintf(out, " \n"); + } + + if (this->authKeyID.ptr) + { + fprintf(out, " authkey: %#B\n", &this->authKeyID); + } + if (this->authKeySerialNumber.ptr) + { + fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber); + } } /** @@ -638,6 +707,7 @@ x509ac_t *x509ac_create_from_chunk(chunk_t chunk) /* public functions */ this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid; + this->public.list = (void(*)(x509ac_t*, FILE *out, bool utc))list; this->public.destroy = (void (*) (x509ac_t*))destroy; if (!parse_certificate(chunk, this)) diff --git a/src/libstrongswan/crypto/ac.h b/src/libstrongswan/crypto/ac.h index b7fd26c94..1886d4971 100644 --- a/src/libstrongswan/crypto/ac.h +++ b/src/libstrongswan/crypto/ac.h @@ -48,6 +48,15 @@ struct x509ac_t { */ err_t (*is_valid) (const x509ac_t *this, time_t *until); + /** + * @brief Log the attribute certificate info to out. + * + * @param this calling object + * @param out stream to write to + * @param utc TRUE for UTC times, FALSE for local time + */ + void (*list)(x509ac_t *this, FILE *out, bool utc); + /** * @brief Destroys the attribute certificate. *