adding attribute certficates to a chained list
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 14 Aug 2007 12:27:02 +0000 (12:27 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 14 Aug 2007 12:27:02 +0000 (12:27 -0000)
src/charon/config/credentials/local_credential_store.c
src/libstrongswan/crypto/ac.c
src/libstrongswan/crypto/ac.h

index 60a0177..3bd1db3 100644 (file)
@@ -258,7 +258,6 @@ static status_t get_key(linked_list_t *keys,
        }
 }
 
-
 /**
  * Implementation of local_credential_store_t.get_shared_key.
  */    
@@ -1093,9 +1092,32 @@ 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 replace stale attribute certificates by fresh ones */
+       iterator_t *iterator;
+       x509ac_t *current_cert;
+
        pthread_mutex_lock(&(this->acerts_mutex));
-       this->acerts->insert_last(this->acerts, (void*)cert);
+       iterator = this->acerts->create_iterator(this->acerts, TRUE);
+
+       while (iterator->iterate(iterator, (void **)&current_cert))
+       {
+               if (cert->equals_holder(cert, current_cert))
+               {
+                       if (cert->is_newer(cert, current_cert))
+                       {
+                               iterator->replace(iterator, NULL, (void *)cert);
+                               current_cert->destroy(current_cert);
+                               DBG1(DBG_CFG, "  this attr cert is newer - existing attr cert replaced");
+                       }
+                       else
+                       {
+                               cert->destroy(cert);
+                               DBG1(DBG_CFG, "  this attr cert is not newer - existing attr cert retained");
+                       }
+                       break;
+               }
+       }
+
+       iterator->destroy(iterator);
        pthread_mutex_unlock(&(this->acerts_mutex));
 }
 
index 29431ad..d92c7b8 100644 (file)
@@ -175,6 +175,42 @@ struct ietfAttr_t {
 };
 
 /**
+ * Lists a linked_list of ietfAttr_t objects
+ */
+static void ietfAttr_list(linked_list_t *list, FILE *out)
+{
+       iterator_t *iterator = list->create_iterator(list, TRUE);
+       ietfAttr_t *attr;
+       bool first = TRUE;
+
+       while (iterator->iterate(iterator, (void **)&attr))
+       {
+               if (first)
+               {
+                       first = FALSE;
+               }
+               else
+               {
+                       fprintf(out, ", ");
+               }
+
+               switch (attr->kind)
+               {
+                       case IETF_ATTRIBUTE_OCTETS:
+                       case IETF_ATTRIBUTE_STRING:
+                               fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
+                               break;
+                       case IETF_ATTRIBUTE_OID:
+                               fprintf(out, "0x#B", &attr->value);
+                       break;
+                       default:
+                       break;
+               }
+       }
+       iterator->destroy(iterator);
+}
+
+/**
  * Destroys an ietfAttr_t object
  */
 static void ietfAttr_destroy(ietfAttr_t *this)
@@ -361,6 +397,23 @@ static err_t is_valid(const private_x509ac_t *this, time_t *until)
 }
 
 /**
+ * Implements x509ac_t.is_newer
+ */
+static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other)
+{
+       return this->notBefore > other->notBefore;
+}
+
+/**
+ * Implements x509ac_t.equals_holder.
+ */
+static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other)
+{
+       return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer)
+                  && chunk_equals(this->holderSerial, other->holderSerial);
+}
+
+/**
  * parses a directoryName
  */
 static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
@@ -613,7 +666,7 @@ static bool parse_certificate(chunk_t blob, private_x509ac_t *this)
 /**
  * Implementation of x509ac_t.list.
  */
-static void list(private_x509ac_t *this, FILE *out, bool utc)
+static void list(const private_x509ac_t *this, FILE *out, bool utc)
 {
        time_t now = time(NULL);
 
@@ -631,12 +684,12 @@ static void list(private_x509ac_t *this, FILE *out, bool utc)
        {
                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);
-       } 
-*/
+       
+       /* list all group attributes on a single line */
+       fprintf(out, "    groups:     ");
+       ietfAttr_list(this->groups, out);
+       fprintf(out, "\n");
+
        fprintf(out, "    issuer:    '%D'\n", this->issuerName);
        fprintf(out, "    serial:     %#B\n", &this->serialNumber);
 
@@ -707,7 +760,9 @@ 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.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer;
+       this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder;
+       this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list;
        this->public.destroy = (void (*) (x509ac_t*))destroy;
 
        if (!parse_certificate(chunk, this))
index 1886d49..dc34429 100644 (file)
@@ -48,6 +48,23 @@ struct x509ac_t {
         */
        err_t (*is_valid) (const x509ac_t *this, time_t *until);
 
+       /** @brief Checks if this attr cert is newer than the other attr cert
+        * 
+        * @param this                  calling object
+        * @param other                 other attr cert object
+        * @return                              TRUE if this was issued more recently than other
+        */
+       bool (*is_newer) (const x509ac_t *this, const x509ac_t *other);
+
+       /**
+        * @brief Checks if two attribute certificates belong to the same holder
+        *
+        * @param this                  calling attribute certificate
+        * @param that                  other attribute certificate
+        * @return                              TRUE if same holder
+        */
+       bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other);
+
        /**
         * @brief Log the attribute certificate info to out.
         *
@@ -55,7 +72,7 @@ struct x509ac_t {
         * @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);
+       void (*list)(const x509ac_t *this, FILE *out, bool utc);
 
        /**
         * @brief Destroys the attribute certificate.