pluto now uses x509 plugin for attribute certificate handling
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 5 Oct 2009 05:24:28 +0000 (07:24 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 5 Oct 2009 05:24:28 +0000 (07:24 +0200)
28 files changed:
src/libstrongswan/Makefile.am
src/libstrongswan/credentials/certificates/ac.h
src/libstrongswan/credentials/certificates/x509.c
src/libstrongswan/credentials/certificates/x509.h
src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c [new file with mode: 0644]
src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h [new file with mode: 0644]
src/libstrongswan/plugins/x509/Makefile.am
src/libstrongswan/plugins/x509/ietf_attr_list.c [deleted file]
src/libstrongswan/plugins/x509/ietf_attr_list.h [deleted file]
src/libstrongswan/plugins/x509/x509_ac.c
src/openac/openac.c
src/pluto/ac.c
src/pluto/ac.h
src/pluto/builder.c
src/pluto/ca.c
src/pluto/ca.h
src/pluto/certs.c
src/pluto/certs.h
src/pluto/connections.c
src/pluto/connections.h
src/pluto/crl.c
src/pluto/ipsec_doi.c
src/pluto/ocsp.c
src/pluto/plutomain.c
src/pluto/rcv_whack.c
src/pluto/x509.c
src/pluto/x509.h
testing/tests/ikev1/attr-cert/evaltest.dat

index f97d420..5a53cc5 100644 (file)
@@ -36,6 +36,7 @@ credentials/certificates/pkcs10.h \
 credentials/certificates/ocsp_request.h \
 credentials/certificates/ocsp_response.h credentials/certificates/ocsp_response.c \
 credentials/certificates/pgp_certificate.h \
+credentials/ietf_attributes/ietf_attributes.c credentials/ietf_attributes/ietf_attributes.h \
 database/database.h database/database_factory.h database/database_factory.c \
 fetcher/fetcher.h fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
 utils.h utils.c \
index 50fd788..fef7f8c 100644 (file)
@@ -1,9 +1,7 @@
 /*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2008 Andreas Steffen
+ * Copyright (C) 2002-2009 Andreas Steffen
  *
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -26,6 +24,7 @@
 
 #include <library.h>
 #include <credentials/certificates/certificate.h>
+#include <credentials/ietf_attributes/ietf_attributes.h>
 
 typedef struct ac_t ac_t;
 
@@ -64,13 +63,20 @@ struct ac_t {
        identification_t* (*get_holderIssuer)(ac_t *this);
 
        /**
-        * Get the thauthorityKeyIdentifier.
+        * Get the authorityKeyIdentifier.
         *
         * @return                      authKeyIdentifier as chunk_t, to internal data
         */
        chunk_t (*get_authKeyIdentifier)(ac_t *this);
 
        /**
+        * Get the group memberships as a list of IETF attributes
+        *
+        * @return                      object containing a list of IETF attributes
+        */
+       ietf_attributes_t* (*get_groups)(ac_t *this);
+
+       /**
         * @brief Checks if two attribute certificates belong to the same holder
         *
         * @param this                  calling attribute certificate
index 5d53f0c..0a75056 100644 (file)
@@ -15,7 +15,8 @@
 
 #include "x509.h"
 
-ENUM(x509_flag_names, X509_CA, X509_SELF_SIGNED,
+ENUM(x509_flag_names, X509_NONE, X509_SELF_SIGNED,
+       "X509_NONE",
        "X509_CA",
        "X509_AA",
        "X509_OCSP_SIGNER",
index b3253a2..a700238 100644 (file)
@@ -31,6 +31,8 @@ typedef enum x509_flag_t x509_flag_t;
  * X.509 certificate flags.
  */
 enum x509_flag_t {
+       /** cert has no constraints */
+       X509_NONE =                     0, 
        /** cert has CA constraint */
        X509_CA =                       (1<<0),
        /** cert has AA constraint */
diff --git a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c
new file mode 100644 (file)
index 0000000..ff3ddeb
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * Copyright (C) 2007-2009 Andreas Steffen
+ *
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <utils/linked_list.h>
+#include <utils/lexparser.h>
+
+#include "ietf_attributes.h"
+
+/**
+ * Private definition of IETF attribute types
+ */
+typedef enum {
+       IETF_ATTRIBUTE_OCTETS = 0,
+       IETF_ATTRIBUTE_OID =    1,
+       IETF_ATTRIBUTE_STRING = 2
+} ietf_attribute_type_t;
+
+typedef struct ietf_attr_t ietf_attr_t;
+
+/**
+ * Private definition of an IETF attribute
+ */
+struct ietf_attr_t {
+       /**
+        * IETF attribute type
+        */
+       ietf_attribute_type_t type;
+
+       /**
+        * IETF attribute value
+        */
+       chunk_t value;
+
+       /**
+        * Compares two IETF attributes
+        *
+        * return -1 if this is earlier in the alphabet than other
+        * return  0 if this equals other
+        * return +1 if this is later in the alphabet than other
+        *
+        * @param other         other object
+        */
+       int (*compare) (ietf_attr_t *this, ietf_attr_t *other);
+
+       /**
+        * Destroys an ietf_attr_t object.
+        */
+       void (*destroy) (ietf_attr_t *this);
+};
+
+/**
+ * Implements ietf_attr_t.compare.
+ */
+static int ietf_attr_compare(ietf_attr_t *this, ietf_attr_t *other)
+{
+       int cmp_len, len, cmp_value;
+
+       /* OID attributes are appended after STRING and OCTETS attributes */
+       if (this->type != IETF_ATTRIBUTE_OID && other->type == IETF_ATTRIBUTE_OID)
+       {
+               return -1;
+       }
+       if (this->type == IETF_ATTRIBUTE_OID && other->type != IETF_ATTRIBUTE_OID)
+       {
+               return 1;
+       }
+
+       cmp_len = this->value.len - other->value.len;
+       len = (cmp_len < 0) ? this->value.len : other->value.len;
+       cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
+
+       return (cmp_value == 0) ? cmp_len : cmp_value;
+}
+
+/**
+ * Implements ietf_attr_t.destroy.
+ */
+static void ietf_attr_destroy(ietf_attr_t *this)
+{
+       free(this->value.ptr);
+       free(this);
+}
+
+/**
+ * Creates an ietf_attr_t object.
+ */
+static ietf_attr_t* ietf_attr_create(ietf_attribute_type_t type, chunk_t value)
+{
+       ietf_attr_t *this = malloc_thing(ietf_attr_t);
+
+       /* initialize */
+       this->type = type;
+       this->value = chunk_clone(value);
+
+       /* function */
+       this->compare = ietf_attr_compare;
+       this->destroy = ietf_attr_destroy;
+
+       return this;
+}
+
+typedef struct private_ietf_attributes_t private_ietf_attributes_t;
+
+/**
+ * Private data of an ietf_attributes_t object.
+ */
+struct private_ietf_attributes_t {
+       /**
+        * Public interface.
+        */
+       ietf_attributes_t public;
+
+       /**
+        * Printable representation of the IETF attributes
+        */
+       char *string;
+
+       /**
+        * Linked list of IETF attributes.
+        */
+       linked_list_t *list;
+
+       /**
+        * reference count
+        */
+       refcount_t ref;
+};
+
+/**
+ * Implementation of ietf_attributes_t.get_string.
+ */
+static char* get_string(private_ietf_attributes_t *this)
+{
+       if (this->string == NULL)
+       {
+               char buf[BUF_LEN];
+               char *pos = buf;
+               int len = BUF_LEN;
+               bool first = TRUE;
+               ietf_attr_t *attr;
+               enumerator_t *enumerator;
+
+               enumerator = this->list->create_enumerator(this->list);
+               while (enumerator->enumerate(enumerator, &attr))
+               {
+                       int written = 0;
+
+                       if (first)
+                       {
+                               first = FALSE;
+                       }
+                       else
+                       {
+                               written = snprintf(pos, len, ", ");
+                               pos += written;
+                               len -= written; 
+                       }
+
+                       switch (attr->type)
+                       {
+                               case IETF_ATTRIBUTE_OCTETS:
+                               case IETF_ATTRIBUTE_STRING:
+                                       written = snprintf(pos, len, "%.*s", (int)attr->value.len,
+                                                                                                                attr->value.ptr);
+                                       break;
+                               case IETF_ATTRIBUTE_OID:
+                               {
+                                       int oid = asn1_known_oid(attr->value);
+
+                                       if (oid == OID_UNKNOWN)
+                                       {
+                                               written = snprintf(pos, len, "0x#B", &attr->value);
+                                       }
+                                       else
+                                       {
+                                               written = snprintf(pos, len, "%s", oid_names[oid]);
+                                       }
+                                       break;
+                               }
+                               default:
+                                       break;
+                       }
+                       pos += written;
+                       len -= written;
+               }
+               enumerator->destroy(enumerator);
+               if (len < BUF_LEN)
+               {
+                       this->string = strdup(buf);
+               }
+       }
+       return this->string;
+}
+
+/**
+ * Implementation of ietf_attributes_t.get_encoding.
+ */
+static chunk_t get_encoding(private_ietf_attributes_t *this)
+{
+       chunk_t values;
+       size_t size = 0;
+       u_char *pos;
+       ietf_attr_t *attr;
+       enumerator_t *enumerator;
+
+       /* precalculate the total size of all values */
+       enumerator = this->list->create_enumerator(this->list);
+       while (enumerator->enumerate(enumerator, &attr))
+       {
+               size_t len = attr->value.len;
+
+               size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
+       }
+       enumerator->destroy(enumerator);
+
+       pos = asn1_build_object(&values, ASN1_SEQUENCE, size);
+
+       enumerator = this->list->create_enumerator(this->list);
+       while (enumerator->enumerate(enumerator, &attr))
+       {
+               chunk_t ietfAttribute;
+               asn1_t type = ASN1_NULL;
+
+               switch (attr->type)
+               {
+                       case IETF_ATTRIBUTE_OCTETS:
+                               type = ASN1_OCTET_STRING;
+                               break;
+                       case IETF_ATTRIBUTE_STRING:
+                               type = ASN1_UTF8STRING;
+                               break;
+                       case IETF_ATTRIBUTE_OID:
+                               type = ASN1_OID;
+                               break;
+               }
+               ietfAttribute = asn1_simple_object(type, attr->value);
+
+               /* copy ietfAttribute into values chunk */
+               memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
+               pos += ietfAttribute.len;
+               free(ietfAttribute.ptr);
+       }
+       enumerator->destroy(enumerator);
+
+       return asn1_wrap(ASN1_SEQUENCE, "m", values);
+}
+
+static bool equals(private_ietf_attributes_t *this, private_ietf_attributes_t *other)
+{
+        bool result = TRUE;
+
+       /* lists must have the same number of attributes */
+       if (other == NULL ||
+               this->list->get_count(this->list) != other->list->get_count(other->list))
+       {
+               return FALSE;
+       }
+
+       /* compare two alphabetically-sorted lists */
+       {
+               ietf_attr_t *attr_a, *attr_b;
+               enumerator_t *enum_a, *enum_b;
+
+               enum_a = this->list->create_enumerator(this->list);
+               enum_b = other->list->create_enumerator(other->list);
+               while (enum_a->enumerate(enum_a, &attr_a) &&
+                          enum_b->enumerate(enum_b, &attr_b))
+               {
+                       if (attr_a->compare(attr_a, attr_b) != 0)
+                       {
+                               /* we have a mismatch */
+                               result = FALSE;
+                               break;
+                       }
+               }
+               enum_a->destroy(enum_a);
+               enum_b->destroy(enum_b);
+       }
+       return result;
+}
+
+static bool matches(private_ietf_attributes_t *this, private_ietf_attributes_t *other)
+{
+       bool result = FALSE;
+       ietf_attr_t *attr_a, *attr_b;
+       enumerator_t *enum_a, *enum_b;
+
+       /* always match if this->list does not contain any attributes */
+       if (this->list->get_count(this->list) == 0)
+       {
+               return TRUE;
+       }
+
+       /* never match if other->list does not contain any attributes */
+       if (other == NULL || other->list->get_count(other->list) == 0)
+       {
+               return FALSE;
+       }
+
+       /* get first attribute from both lists */
+       enum_a = this->list->create_enumerator(this->list);
+       enum_a->enumerate(enum_a, &attr_a);
+       enum_b = other->list->create_enumerator(other->list);
+       enum_b->enumerate(enum_b, &attr_b);
+
+       /* look for at least one common attribute */
+       while (TRUE)
+       {
+               bool cmp = attr_a->compare(attr_a, attr_b);
+
+               if (cmp == 0)
+               {
+                       /* we have a match */
+                       result = TRUE;
+                       break;
+               }
+               if (cmp == -1)
+               {
+                       /* attr_a is earlier in the alphabet, get next attr_a */
+                       if (!enum_a->enumerate(enum_a, &attr_a))
+                       {
+                               /* we have reached the end of enum_a */
+                               break;
+                       }
+               }
+               else
+               {
+                       /* attr_a is later in the alphabet, get next attr_b */
+                       if (!enum_b->enumerate(enum_b, &attr_b))
+                       {
+                               /* we have reached the end of enum_b */
+                               break;
+                       }
+               }
+       }
+       enum_a->destroy(enum_a);
+       enum_b->destroy(enum_b);
+
+       return result;
+}
+
+/**
+ * Implementation of ietf_attributes_t.get_ref
+ */
+static private_ietf_attributes_t* get_ref(private_ietf_attributes_t *this)
+{
+       ref_get(&this->ref);
+       return this;
+}
+
+/**
+ * Implementation of ietf_attributes_t.destroy.
+ */
+static void destroy(private_ietf_attributes_t *this)
+{
+       if (ref_put(&this->ref))
+       {
+               this->list->destroy_offset(this->list, offsetof(ietf_attr_t, destroy));
+               free(this->string);
+               free(this);
+       }
+}
+
+static private_ietf_attributes_t* create_empty(void)
+{
+       private_ietf_attributes_t *this = malloc_thing(private_ietf_attributes_t);
+
+       this->public.get_string = (char* (*)(ietf_attributes_t*))get_string;
+       this->public.get_encoding = (chunk_t (*)(ietf_attributes_t*))get_encoding;
+       this->public.equals = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))equals;
+       this->public.matches = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))matches;
+       this->public.get_ref = (ietf_attributes_t* (*)(ietf_attributes_t*))get_ref;
+       this->public.destroy = (void (*)(ietf_attributes_t*))destroy;
+
+       this->list = linked_list_create();
+       this->string = NULL;
+       this->ref = 1;
+       return this;
+}
+
+/**
+ * Adds an ietf_attr_t object to a sorted linked list
+ */
+static void ietf_attributes_add(private_ietf_attributes_t *this,
+                                                               ietf_attr_t *attr)
+{
+       ietf_attr_t *current_attr;
+       bool found = FALSE;
+       iterator_t *iterator;
+
+       iterator = this->list->create_iterator(this->list, TRUE);
+       while (iterator->iterate(iterator, (void **)&current_attr))
+       {
+               int cmp = attr->compare(attr, current_attr);
+
+               if (cmp > 0)
+               {
+                        continue;
+               }
+               if (cmp == 0)
+               {
+                       attr->destroy(attr);
+               }
+               else
+               {
+                       iterator->insert_before(iterator, attr);
+               }
+               found = TRUE;
+               break;
+       }
+       iterator->destroy(iterator);
+       if (!found)
+       {
+               this->list->insert_last(this->list, attr);
+       }
+}
+
+/*
+ * Described in header.
+ */
+ietf_attributes_t *ietf_attributes_create_from_string(char *string)
+{
+       private_ietf_attributes_t *this = create_empty();
+
+       chunk_t line = { string, strlen(string) };
+
+       while (eat_whitespace(&line))
+       {
+               chunk_t group;
+
+               /* extract the next comma-separated group attribute */
+               if (!extract_token(&group, ',', &line))
+               {
+                       group = line;
+                       line.len = 0;
+               }
+
+               /* remove any trailing spaces */
+               while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
+               {
+                       group.len--;
+               }
+
+               /* add the group attribute to the list */
+               if (group.len > 0)
+               {
+                       ietf_attr_t *attr = ietf_attr_create(IETF_ATTRIBUTE_STRING, group);
+
+                       ietf_attributes_add(this, attr);
+               }
+       }
+
+       return &(this->public);
+}
+
+/**
+ * ASN.1 definition of ietfAttrSyntax
+ */
+static const asn1Object_t ietfAttrSyntaxObjects[] =
+{
+       { 0, "ietfAttrSyntax",          ASN1_SEQUENCE,          ASN1_NONE }, /*  0 */
+       { 1,   "policyAuthority",       ASN1_CONTEXT_C_0,       ASN1_OPT |
+                                                                                                       ASN1_BODY }, /*  1 */
+       { 1,   "end opt",                       ASN1_EOC,                       ASN1_END  }, /*  2 */
+       { 1,   "values",                        ASN1_SEQUENCE,          ASN1_LOOP }, /*  3 */
+       { 2,     "octets",                      ASN1_OCTET_STRING,      ASN1_OPT |
+                                                                                                       ASN1_BODY }, /*  4 */
+       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  5 */
+       { 2,     "oid",                         ASN1_OID,                       ASN1_OPT |
+                                                                                                       ASN1_BODY }, /*  6 */
+       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  7 */
+       { 2,     "string",                      ASN1_UTF8STRING,        ASN1_OPT |
+                                                                                                       ASN1_BODY }, /*  8 */
+       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  9 */
+       { 1,   "end loop",                      ASN1_EOC,                       ASN1_END  }, /* 10 */
+       { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT }
+};
+#define IETF_ATTR_OCTETS        4
+#define IETF_ATTR_OID           6
+#define IETF_ATTR_STRING        8
+
+/*
+ * Described in header.
+ */
+ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded)
+{
+       private_ietf_attributes_t *this = create_empty();
+       asn1_parser_t *parser;
+       chunk_t object;
+       int objectID;
+
+       parser = asn1_parser_create(ietfAttrSyntaxObjects, encoded);
+       while (parser->iterate(parser, &objectID, &object))
+       {
+               switch (objectID)
+               {
+                       case IETF_ATTR_OCTETS:
+                       case IETF_ATTR_OID:
+                       case IETF_ATTR_STRING:
+                               {
+                                       ietf_attribute_type_t type;
+                                       ietf_attr_t *attr;
+
+                                       type = (objectID - IETF_ATTR_OCTETS) / 2;
+                                       attr   = ietf_attr_create(type, object);
+                                       ietf_attributes_add(this, attr);
+                               }
+                               break;
+                       default:
+                               break;
+               }
+       }
+       parser->destroy(parser);
+
+       return &(this->public);
+}
+
diff --git a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h
new file mode 100644 (file)
index 0000000..ab6bae9
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2009 Andreas Steffen
+ *
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup ietf_attributes ietf_attributes
+ * @{ @ingroup credentials
+ */
+
+#ifndef IETF_ATTRIBUTES_H_
+#define IETF_ATTRIBUTES_H_
+
+typedef struct ietf_attributes_t ietf_attributes_t;
+
+#include <library.h>
+
+/**
+ *
+ */
+struct ietf_attributes_t {
+
+       /**
+        * Get the an alphabetically sorted list of printable IETF attributes.
+        *
+        * Result points to internal data, do not free.
+        *
+        * @return                      a string containing printable attributes
+        */
+       char* (*get_string) (ietf_attributes_t *this);
+
+       /**
+        * Get the ASN.1 encoding of the IETF attributes.
+        *
+        * @return                      allocated chunk containing the encoded bytes
+        */
+       chunk_t (*get_encoding) (ietf_attributes_t *this);
+
+       /**
+        * Check for equality between two lists.
+        *
+        * @param other         attribute list to be checked for equality
+        * @return                      TRUE if equal
+        */
+       bool (*equals) (ietf_attributes_t *this, ietf_attributes_t *other);
+
+       /**
+        * Check for common attributes between two lists.
+        *
+        * @param other         attribute list to be matched 
+        * @return                      TRUE if there is at least a common attribute
+        */
+       bool (*matches) (ietf_attributes_t *this, ietf_attributes_t *other);
+
+       /**
+        * Get a new reference to the IETF attributes.
+        *
+        * @return                      this, with an increased refcount
+        */
+       ietf_attributes_t* (*get_ref)(ietf_attributes_t *this);
+
+       /**
+        * Destroys an ietf_attributes_t object.
+        */
+       void (*destroy) (ietf_attributes_t *this);
+};
+
+/**
+ * @param string       input string, which will be converted
+ * @return                     ietf_attributes_t
+ */
+ietf_attributes_t *ietf_attributes_create_from_string(char *string);
+
+/**
+ * @param encoded      ASN.1 encoded bytes, such as from ietf_attributes.get_encoding
+ * @return                     ietf_attributes_t
+ */
+ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded);
+
+#endif /** IETF_ATTRIBUTES_H_ @}*/
+
index 560e186..853b1ce 100644 (file)
@@ -11,7 +11,6 @@ libstrongswan_x509_la_SOURCES = x509_plugin.h x509_plugin.c \
   x509_ac.h x509_ac.c \
   x509_pkcs10.h x509_pkcs10.c \
   x509_ocsp_request.h x509_ocsp_request.c \
-  x509_ocsp_response.h x509_ocsp_response.c \
-  ietf_attr_list.h ietf_attr_list.c
+  x509_ocsp_response.h x509_ocsp_response.c
 libstrongswan_x509_la_LDFLAGS = -module -avoid-version
 
diff --git a/src/libstrongswan/plugins/x509/ietf_attr_list.c b/src/libstrongswan/plugins/x509/ietf_attr_list.c
deleted file mode 100644 (file)
index d1ba726..0000000
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <debug.h>
-#include <library.h>
-
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/asn1_parser.h>
-#include <utils/lexparser.h>
-
-#include "ietf_attr_list.h"
-
-/**
- * Private definition of ietfAttribute kinds
- */
-typedef enum {
-       IETF_ATTRIBUTE_OCTETS = 0,
-       IETF_ATTRIBUTE_OID =    1,
-       IETF_ATTRIBUTE_STRING = 2
-} ietfAttribute_t;
-
-typedef struct ietfAttr_t ietfAttr_t;
-
-/**
- * Private definition of an ietfAttribute
- */
-struct ietfAttr_t {
-       /**
-        * IETF attribute kind
-        */
-       ietfAttribute_t kind;
-
-       /**
-        * IETF attribute valuse
-        */
-       chunk_t value;
-
-       /**
-        * Compares two ietfAttributes
-        *
-        * return -1 if this is earlier in the alphabet than other
-        * return  0 if this equals other
-        * return +1 if this is later in the alphabet than other
-        *
-        * @param this          calling object
-        * @param other         other object
-        */
-       int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
-
-       /**
-        * Destroys the ietfAttr_t object.
-        *
-        * @param this                  ietfAttr_t to destroy
-        */
-       void (*destroy) (ietfAttr_t *this);
-};
-
-/**
- * Implements ietfAttr_t.compare.
- */
-static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
-{
-       int cmp_len, len, cmp_value;
-
-       /* OID attributes are appended after STRING and OCTETS attributes */
-       if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
-       {
-               return -1;
-       }
-       if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
-       {
-               return 1;
-       }
-
-       cmp_len = this->value.len - other->value.len;
-       len = (cmp_len < 0)? this->value.len : other->value.len;
-       cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
-
-       return (cmp_value == 0)? cmp_len : cmp_value;
-}
-
-/**
- * Implements ietfAttr_t.destroy.
- */
-static void ietfAttr_destroy(ietfAttr_t *this)
-{
-       free(this->value.ptr);
-       free(this);
-}
-
-/**
- * Creates an ietfAttr_t object.
- */
-static ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
-{
-       ietfAttr_t *this = malloc_thing(ietfAttr_t);
-
-       /* initialize */
-       this->kind = kind;
-       this->value = chunk_clone(value);
-
-       /* function */
-       this->compare = ietfAttr_compare;
-       this->destroy = ietfAttr_destroy;
-
-       return this;
-}
-
-/**
- * Adds an ietfAttr_t object to a sorted linked list
- */
-static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
-{
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       ietfAttr_t *current_attr;
-       bool found = FALSE;
-
-       while (iterator->iterate(iterator, (void **)&current_attr))
-       {
-               int cmp = attr->compare(attr, current_attr);
-
-               if (cmp > 0)
-               {
-                        continue;
-               }
-               if (cmp == 0)
-               {
-                       attr->destroy(attr);
-               }
-               else
-               {
-                       iterator->insert_before(iterator, attr);
-               }
-               found = TRUE;
-               break;
-       }
-       iterator->destroy(iterator);
-       if (!found)
-       {
-               list->insert_last(list, attr);
-       }
-}
-
-/*
- * Described in header.
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b)
-{
-        bool result = TRUE;
-
-       /* lists must have the same number of attributes */
-       if (list_a->get_count(list_a) != list_b->get_count(list_b))
-       {
-               return FALSE;
-       }
-       /* empty lists - no attributes */
-       if (list_a->get_count(list_a) == 0)
-       {
-               return TRUE;
-       }
-
-       /* compare two alphabetically-sorted lists */
-       {
-               iterator_t *iterator_a = list_a->create_iterator(list_a, TRUE);
-               iterator_t *iterator_b = list_b->create_iterator(list_b, TRUE);
-               ietfAttr_t *attr_a, *attr_b;
-
-               while (iterator_a->iterate(iterator_a, (void **)&attr_a) &&
-                          iterator_b->iterate(iterator_b, (void **)&attr_b))
-               {
-                       if (attr_a->compare(attr_a, attr_b) != 0)
-                       {
-                               /* we have a mismatch */
-                               result = FALSE;
-                               break;
-                       }
-               }
-               iterator_a->destroy(iterator_a);
-               iterator_b->destroy(iterator_b);
-       }
-       return result;
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_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:
-                               {
-                                       int oid = asn1_known_oid(attr->value);
-
-                                       if (oid == OID_UNKNOWN)
-                                       {
-                                               fprintf(out, "0x#B", &attr->value);
-                                       }
-                                       else
-                                       {
-                                               fprintf(out, "%s", oid_names[oid]);
-                                       }
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-       iterator->destroy(iterator);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list)
-{
-       chunk_t line = { msg, strlen(msg) };
-
-       while (eat_whitespace(&line))
-       {
-               chunk_t group;
-
-               /* extract the next comma-separated group attribute */
-               if (!extract_token(&group, ',', &line))
-               {
-                       group = line;
-                       line.len = 0;
-               }
-
-               /* remove any trailing spaces */
-               while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
-               {
-                       group.len--;
-               }
-
-               /* add the group attribute to the list */
-               if (group.len > 0)
-               {
-                       ietfAttr_t *attr = ietfAttr_create(IETF_ATTRIBUTE_STRING, group);
-
-                       ietfAttr_add(list, attr);
-               }
-       }
-}
-
-/**
- * ASN.1 definition of ietfAttrSyntax
- */
-static const asn1Object_t ietfAttrSyntaxObjects[] =
-{
-       { 0, "ietfAttrSyntax",          ASN1_SEQUENCE,          ASN1_NONE }, /*  0 */
-       { 1,   "policyAuthority",       ASN1_CONTEXT_C_0,       ASN1_OPT |
-                                                                                                       ASN1_BODY }, /*  1 */
-       { 1,   "end opt",                       ASN1_EOC,                       ASN1_END  }, /*  2 */
-       { 1,   "values",                        ASN1_SEQUENCE,          ASN1_LOOP }, /*  3 */
-       { 2,     "octets",                      ASN1_OCTET_STRING,      ASN1_OPT |
-                                                                                                       ASN1_BODY }, /*  4 */
-       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  5 */
-       { 2,     "oid",                         ASN1_OID,                       ASN1_OPT |
-                                                                                                       ASN1_BODY }, /*  6 */
-       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  7 */
-       { 2,     "string",                      ASN1_UTF8STRING,        ASN1_OPT |
-                                                                                                       ASN1_BODY }, /*  8 */
-       { 2,     "end choice",          ASN1_EOC,                       ASN1_END  }, /*  9 */
-       { 1,   "end loop",                      ASN1_EOC,                       ASN1_END  }, /* 10 */
-       { 0, "exit",                            ASN1_EOC,                       ASN1_EXIT }
-};
-#define IETF_ATTR_OCTETS        4
-#define IETF_ATTR_OID           6
-#define IETF_ATTR_STRING        8
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-
-       parser = asn1_parser_create(ietfAttrSyntaxObjects, chunk);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-                       case IETF_ATTR_OCTETS:
-                       case IETF_ATTR_OID:
-                       case IETF_ATTR_STRING:
-                               {
-                                       ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
-                                       ietfAttr_t *attr   = ietfAttr_create(kind, object);
-                                       ietfAttr_add(list, attr);
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-       parser->destroy(parser);
-}
-
-/*
- * Described in header.
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list)
-{
-       chunk_t ietfAttributes;
-       size_t size = 0;
-       u_char *pos;
-       iterator_t *iterator = list->create_iterator(list, TRUE);
-       ietfAttr_t *attr;
-
-       /* precalculate the total size of all values */
-       while (iterator->iterate(iterator, (void **)&attr))
-       {
-               size_t len = attr->value.len;
-
-               size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
-       }
-       iterator->destroy(iterator);
-
-       pos = asn1_build_object(&ietfAttributes, ASN1_SEQUENCE, size);
-
-       iterator = list->create_iterator(list, TRUE);
-       while (iterator->iterate(iterator, (void **)&attr))
-       {
-               chunk_t ietfAttribute;
-               asn1_t type = ASN1_NULL;
-
-               switch (attr->kind)
-               {
-                       case IETF_ATTRIBUTE_OCTETS:
-                               type = ASN1_OCTET_STRING;
-                               break;
-                       case IETF_ATTRIBUTE_STRING:
-                               type = ASN1_UTF8STRING;
-                               break;
-                       case IETF_ATTRIBUTE_OID:
-                               type = ASN1_OID;
-                               break;
-               }
-               ietfAttribute = asn1_simple_object(type, attr->value);
-
-               /* copy ietfAttribute into ietfAttributes chunk */
-               memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
-               pos += ietfAttribute.len;
-               free(ietfAttribute.ptr);
-       }
-       iterator->destroy(iterator);
-
-       return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_destroy(linked_list_t *list)
-{
-       list->destroy_offset(list, offsetof(ietfAttr_t, destroy));
-}
diff --git a/src/libstrongswan/plugins/x509/ietf_attr_list.h b/src/libstrongswan/plugins/x509/ietf_attr_list.h
deleted file mode 100644 (file)
index 124468b..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup ietf_attr_list ietf_attr_list
- * @{ @ingroup x509_p
- */
-
-#ifndef IETF_ATTR_LIST_H_
-#define IETF_ATTR_LIST_H_
-
-#include <library.h>
-#include <utils/linked_list.h>
-
-
-/**
- * @brief Compare two linked lists of ietfAttr_t objects for equality
- *
- * @param list_a       first alphabetically-sorted list
- * @param list_b       second alphabetically-sorted list
- * @return                     TRUE if equal
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
-
-/**
- * @brief Lists a linked list of ietfAttr_t objects
- *
- * @param list         alphabetically-sorted linked list of attributes
- * @param out          output file
- */
-void ietfAttr_list_list(linked_list_t *list, FILE *out);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from a string
- *
- * @param msg          string with comma-separated group names
- * @param list         alphabetically-sorted linked list of attributes
-  */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from an ASN.1-coded chunk
- *
- * @param chunk                chunk containing ASN.1-coded attributes
- * @param list         alphabetically-sorted linked list of attributes
- * @param level0       parsing level
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
-
-/**
- * @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
- *
- * @param list         alphabetically-sorted linked list of attributes
- * @return                     chunk containing ASN.1-coded attributes
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list);
-
-/**
- * @brief Destroys a linked list of ietfAttr_t objects
- *
- * @param list         list to be destroyed
- */
-void ietfAttr_list_destroy(linked_list_t *list);
-
-#endif /** IETF_ATTR_LIST_H_ @}*/
-
index 878406a..5e8ea2e 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
  * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2008 Andreas Steffen
+ * Copyright (C) 2002-2009 Andreas Steffen
  * Copyright (C) 2009 Martin Willi
  *
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,7 +18,6 @@
  */
 
 #include "x509_ac.h"
-#include "ietf_attr_list.h"
 
 #include <time.h>
 
@@ -30,6 +29,7 @@
 #include <utils/identification.h>
 #include <utils/linked_list.h>
 #include <credentials/certificates/x509.h>
+#include <credentials/ietf_attributes/ietf_attributes.h>
 #include <credentials/keys/private_key.h>
 
 extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob,
@@ -100,12 +100,12 @@ struct private_x509_ac_t {
        /**
         * List of charging attributes
         */
-       linked_list_t *charging;
+       ietf_attributes_t *charging;
 
        /**
         * List of groub attributes
         */
-       linked_list_t *groups;
+       ietf_attributes_t *groups;
 
        /**
         * Authority Key Identifier
@@ -413,10 +413,14 @@ static bool parse_certificate(private_x509_ac_t *this)
                                                DBG2("  need to parse accessIdentity");
                                                break;
                                        case OID_CHARGING_IDENTITY:
-                                               ietfAttr_list_create_from_chunk(object, this->charging, level);
+                                               DBG2("-- > --");
+                                               this->charging = ietf_attributes_create_from_encoding(object);
+                                               DBG2("-- < --");
                                                break;
                                        case OID_GROUP:
-                                               ietfAttr_list_create_from_chunk(object, this->groups, level);
+                                               DBG2("-- > --");
+                                               this->groups = ietf_attributes_create_from_encoding(object);
+                                               DBG2("-- < --");
                                                break;
                                        case OID_ROLE:
                                                parse_roleSyntax(object, level);
@@ -543,7 +547,7 @@ static chunk_t build_attribute_type(int type, chunk_t content)
 static chunk_t build_attributes(private_x509_ac_t *this)
 {
        return asn1_wrap(ASN1_SEQUENCE, "m",
-               build_attribute_type(OID_GROUP, ietfAttr_list_encode(this->groups)));
+               build_attribute_type(OID_GROUP, this->groups->get_encoding(this->groups)));
 }
 
 /**
@@ -664,6 +668,14 @@ static chunk_t get_authKeyIdentifier(private_x509_ac_t *this)
 }
 
 /**
+ * Implementation of certificate_t.get_groups.
+ */
+static ietf_attributes_t* get_groups(private_x509_ac_t *this)
+{
+       return this->groups ? this->groups->get_ref(this->groups) : NULL;
+}
+
+/**
  * Implementation of certificate_t.get_type
  */
 static certificate_type_t get_type(private_x509_ac_t *this)
@@ -881,9 +893,8 @@ static void destroy(private_x509_ac_t *this)
                DESTROY_IF(this->holderCert);
                DESTROY_IF(this->signerCert);
                DESTROY_IF(this->signerKey);
-
-               ietfAttr_list_destroy(this->charging);
-               ietfAttr_list_destroy(this->groups);
+               DESTROY_IF(this->charging);
+               DESTROY_IF(this->groups);
                free(this->serialNumber.ptr);
                free(this->authKeyIdentifier.ptr);
                free(this->encoding.ptr);
@@ -902,7 +913,8 @@ static private_x509_ac_t *create_empty(void)
        this->public.interface.get_serial = (chunk_t (*)(ac_t*))get_serial;
        this->public.interface.get_holderSerial = (chunk_t (*)(ac_t*))get_holderSerial;
        this->public.interface.get_holderIssuer = (identification_t* (*)(ac_t*))get_holderIssuer;
-       this->public.interface.get_authKeyIdentifier = (chunk_t(*)(ac_t*))get_authKeyIdentifier;
+       this->public.interface.get_authKeyIdentifier = (chunk_t (*)(ac_t*))get_authKeyIdentifier;
+       this->public.interface.get_groups = (ietf_attributes_t* (*)(ac_t*))get_groups;
        this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
        this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
        this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
@@ -928,8 +940,8 @@ static private_x509_ac_t *create_empty(void)
        this->holderCert = NULL;
        this->signerCert = NULL;
        this->signerKey = NULL;
-       this->charging = linked_list_create();
-       this->groups = linked_list_create();
+       this->charging = NULL;
+       this->groups = NULL;
        this->ref = 1;
 
        return this;
@@ -992,7 +1004,7 @@ x509_ac_t *x509_ac_gen(certificate_type_t type, va_list args)
                                ac->serialNumber = chunk_clone(va_arg(args, chunk_t));
                                continue;
                        case BUILD_IETF_GROUP_ATTR:
-                               ietfAttr_list_create_from_string(va_arg(args, char*), ac->groups);
+                               ac->groups = ietf_attributes_create_from_string(va_arg(args, char*));
                                continue;
                        case BUILD_CERT:
                                ac->holderCert = va_arg(args, certificate_t*);
index 407ce36..89acc06 100755 (executable)
@@ -448,7 +448,6 @@ int main(int argc, char **argv)
                signerCert = lib->creds->create(lib->creds,
                                                                                CRED_CERTIFICATE, CERT_X509,
                                                                                BUILD_FROM_FILE, certfile,
-                                                                               BUILD_X509_FLAG, 0,
                                                                                BUILD_END);
                if (signerCert == NULL)
                {
@@ -462,7 +461,6 @@ int main(int argc, char **argv)
                userCert = lib->creds->create(lib->creds,
                                                                          CRED_CERTIFICATE, CERT_X509,
                                                                          BUILD_FROM_FILE, usercertfile,
-                                                                         BUILD_X509_FLAG, 0,
                                                                          BUILD_END);
                if (userCert == NULL)
                {
index 96cc9b2..e352458 100644 (file)
@@ -1,6 +1,7 @@
 /* Support of X.509 attribute certificates
  * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
  * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2009 Andreas Steffen
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
 #include <string.h>
 #include <unistd.h>
 #include <dirent.h>
-#include <time.h>
 #include <sys/types.h>
 
 #include <freeswan.h>
 
 #include <utils.h>
-#include <asn1/asn1.h>
-#include <asn1/asn1_parser.h>
-#include <asn1/oid.h>
-#include <credentials/certificates/certificate.h>
+#include <credentials/certificates/ac.h>
 
 #include "ac.h"
 #include "x509.h"
 static x509acert_t *x509acerts   = NULL;
 
 /**
- * Chained list of ietfAttributes
- */
-static ietfAttrList_t *ietfAttributes = NULL;
-
-/**
- * ASN.1 definition of ietfAttrSyntax
- */
-static const asn1Object_t ietfAttrSyntaxObjects[] =
-{
-       { 0, "ietfAttrSyntax",                ASN1_SEQUENCE,        ASN1_NONE }, /*  0 */
-       { 1,   "policyAuthority",             ASN1_CONTEXT_C_0,     ASN1_OPT |
-                                                                                                                               ASN1_BODY }, /*  1 */
-       { 1,   "end opt",                     ASN1_EOC,             ASN1_END  }, /*  2 */
-       { 1,   "values",                      ASN1_SEQUENCE,        ASN1_LOOP }, /*  3 */
-       { 2,     "octets",                    ASN1_OCTET_STRING,    ASN1_OPT |
-                                                                                                                               ASN1_BODY }, /*  4 */
-       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  5 */
-       { 2,     "oid",                       ASN1_OID,             ASN1_OPT |
-                                                                                                                               ASN1_BODY }, /*  6 */
-       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  7 */
-       { 2,     "string",                    ASN1_UTF8STRING,      ASN1_OPT |
-                                                                                                                               ASN1_BODY }, /*  8 */
-       { 2,     "end choice",                ASN1_EOC,             ASN1_END  }, /*  9 */
-       { 1,   "end loop",                    ASN1_EOC,             ASN1_END  }, /* 10 */
-       { 0, "exit",                          ASN1_EOC,             ASN1_EXIT }
-};
-
-#define IETF_ATTR_OCTETS         4
-#define IETF_ATTR_OID            6
-#define IETF_ATTR_STRING         8
-
-/**
- * ASN.1 definition of roleSyntax
- */
-static const asn1Object_t roleSyntaxObjects[] =
-{
-       { 0, "roleSyntax",              ASN1_SEQUENCE,          ASN1_NONE }, /* 0 */
-       { 1,   "roleAuthority", ASN1_CONTEXT_C_0,       ASN1_OPT |
-                                                                                               ASN1_OBJ  }, /* 1 */
-       { 1,   "end opt",               ASN1_EOC,                       ASN1_END  }, /* 2 */
-       { 1,   "roleName",              ASN1_CONTEXT_C_1,       ASN1_OBJ  }, /* 3 */
-       { 0, "exit",                    ASN1_EOC,                       ASN1_EXIT }
-};
-
-/**
- * ASN.1 definition of an X509 attribute certificate
- */
-static const asn1Object_t acObjects[] =
-{
-       { 0, "AttributeCertificate",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /*  0 */
-       { 1,   "AttributeCertificateInfo",              ASN1_SEQUENCE,            ASN1_OBJ  }, /*  1 */
-       { 2,       "version",                                   ASN1_INTEGER,             ASN1_DEF |
-                                                                                                                                 ASN1_BODY }, /*  2 */
-       { 2,       "holder",                                    ASN1_SEQUENCE,            ASN1_NONE }, /*  3 */
-       { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /*  4 */
-       { 4,           "issuer",                                ASN1_SEQUENCE,            ASN1_OBJ  }, /*  5 */
-       { 4,           "serial",                                ASN1_INTEGER,             ASN1_BODY }, /*  6 */
-       { 4,         "issuerUID",                               ASN1_BIT_STRING,          ASN1_OPT |
-                                                                                                                                 ASN1_BODY }, /*  7 */
-       { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /*  8 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /*  9 */
-       { 3,       "entityName",                                ASN1_CONTEXT_C_1,         ASN1_OPT |
-                                                                                                                                 ASN1_OBJ  }, /* 10 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 11 */
-       { 3,         "objectDigestInfo",                ASN1_CONTEXT_C_2,         ASN1_OPT  }, /* 12 */
-       { 4,           "digestedObjectType",    ASN1_ENUMERATED,          ASN1_BODY }, /* 13 */
-       { 4,           "otherObjectTypeID",             ASN1_OID,                         ASN1_OPT |
-                                                                                                                                 ASN1_BODY }, /* 14 */
-       { 4,         "end opt",                                 ASN1_EOC,                         ASN1_END  }, /* 15 */
-       { 4,         "digestAlgorithm",                 ASN1_EOC,                         ASN1_RAW  }, /* 16 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 17 */
-       { 2,       "v2Form",                                    ASN1_CONTEXT_C_0,         ASN1_NONE }, /* 18 */
-       { 3,         "issuerName",                              ASN1_SEQUENCE,            ASN1_OPT |
-                                                                                                                                 ASN1_OBJ  }, /* 19 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 20 */
-       { 3,         "baseCertificateID",               ASN1_CONTEXT_C_0,         ASN1_OPT  }, /* 21 */
-       { 4,           "issuerSerial",                  ASN1_SEQUENCE,            ASN1_NONE }, /* 22 */
-       { 5,             "issuer",                              ASN1_SEQUENCE,            ASN1_OBJ  }, /* 23 */
-       { 5,             "serial",                                      ASN1_INTEGER,             ASN1_BODY }, /* 24 */
-       { 5,           "issuerUID",                             ASN1_BIT_STRING,          ASN1_OPT |
-                                                                                                                                 ASN1_BODY }, /* 25 */
-       { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 26 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 27 */
-       { 3,       "objectDigestInfo",                  ASN1_CONTEXT_C_1,         ASN1_OPT  }, /* 28 */
-       { 4,           "digestInfo",                    ASN1_SEQUENCE,            ASN1_OBJ  }, /* 29 */
-       { 5,     "digestedObjectType",                  ASN1_ENUMERATED,          ASN1_BODY }, /* 30 */
-       { 5,             "otherObjectTypeID",           ASN1_OID,                         ASN1_OPT |
-                                                                                                                                 ASN1_BODY }, /* 31 */
-       { 5,           "end opt",                               ASN1_EOC,                         ASN1_END  }, /* 32 */
-       { 5,           "digestAlgorithm",               ASN1_EOC,                         ASN1_RAW  }, /* 33 */
-       { 3,       "end opt",                                   ASN1_EOC,                         ASN1_END  }, /* 34 */
-       { 2,       "signature",                                 ASN1_EOC,                         ASN1_RAW  }, /* 35 */
-       { 2,       "serialNumber",                              ASN1_INTEGER,             ASN1_BODY }, /* 36 */
-       { 2,       "attrCertValidityPeriod",    ASN1_SEQUENCE,            ASN1_NONE }, /* 37 */
-       { 3,         "notBeforeTime",                   ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
-       { 3,         "notAfterTime",                    ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
-       { 2,       "attributes",                                ASN1_SEQUENCE,            ASN1_LOOP }, /* 40 */
-       { 3,       "attribute",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 41 */
-       { 4,         "type",                                    ASN1_OID,                         ASN1_BODY }, /* 42 */
-       { 4,         "values",                                  ASN1_SET,                         ASN1_LOOP }, /* 43 */
-       { 5,           "value",                                 ASN1_EOC,                         ASN1_RAW  }, /* 44 */
-       { 4,           "end loop",                              ASN1_EOC,                         ASN1_END  }, /* 45 */
-       { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 46 */
-       { 2,     "extensions",                                  ASN1_SEQUENCE,            ASN1_LOOP }, /* 47 */
-       { 3,       "extension",                                 ASN1_SEQUENCE,            ASN1_NONE }, /* 48 */
-       { 4,         "extnID",                                  ASN1_OID,                         ASN1_BODY }, /* 49 */
-       { 4,         "critical",                                ASN1_BOOLEAN,             ASN1_DEF |
-                                                                                                                                 ASN1_BODY }, /* 50 */
-       { 4,         "extnValue",                               ASN1_OCTET_STRING,        ASN1_BODY }, /* 51 */
-       { 2,     "end loop",                                    ASN1_EOC,                         ASN1_END  }, /* 52 */
-       { 1,   "signatureAlgorithm",                    ASN1_EOC,                         ASN1_RAW  }, /* 53 */
-       { 1,   "signatureValue",                                ASN1_BIT_STRING,          ASN1_BODY }, /* 54 */
-       { 0, "exit",                                                    ASN1_EOC,                         ASN1_EXIT }
-};
-
-#define AC_OBJ_CERTIFICATE               0
-#define AC_OBJ_CERTIFICATE_INFO          1
-#define AC_OBJ_VERSION                   2
-#define AC_OBJ_HOLDER_ISSUER             5
-#define AC_OBJ_HOLDER_SERIAL             6
-#define AC_OBJ_ENTITY_NAME              10
-#define AC_OBJ_ISSUER_NAME              19
-#define AC_OBJ_ISSUER                   23
-#define AC_OBJ_SIG_ALG                  35
-#define AC_OBJ_SERIAL_NUMBER            36
-#define AC_OBJ_NOT_BEFORE               38
-#define AC_OBJ_NOT_AFTER                39
-#define AC_OBJ_ATTRIBUTE_TYPE           42
-#define AC_OBJ_ATTRIBUTE_VALUE          44
-#define AC_OBJ_EXTN_ID                  49
-#define AC_OBJ_CRITICAL                 50
-#define AC_OBJ_EXTN_VALUE               51
-#define AC_OBJ_ALGORITHM                53
-#define AC_OBJ_SIGNATURE                54
-
-const x509acert_t empty_ac = {
-         NULL     , /* *next */
-                       0  , /* installed */
-       { NULL, 0 }, /* certificate */
-       { NULL, 0 }, /*   certificateInfo */
-                       1  , /*     version */
-                                /*     holder */
-                                /*       baseCertificateID */
-       { NULL, 0 }, /*         holderIssuer */
-       { NULL, 0 }, /*         holderSerial */
-                                /*       entityName */
-       { NULL, 0 }, /*         generalNames */
-                                /*     v2Form */
-       { NULL, 0 }, /*       issuerName */
-                                /*     signature */
-       OID_UNKNOWN, /*       sigAlg */
-       { NULL, 0 }, /*     serialNumber */
-                                /*     attrCertValidityPeriod */
-                       0  , /*       notBefore */
-                       0  , /*       notAfter */
-                                /*     attributes */
-         NULL     , /*       charging */
-         NULL     , /*       groups */
-                                /*     extensions */
-       { NULL, 0 }, /*       authKeyID */
-       { NULL, 0 }, /*       authKeySerialNumber */
-         FALSE    , /*       noRevAvail */
-                                /*   signatureAlgorithm */
-       OID_UNKNOWN, /*     algorithm */
-       { NULL, 0 }, /*   signature */
-};
-
-
-/**
- *  compare two ietfAttributes, returns zero if a equals b
- *  negative/positive if a is earlier/later in the alphabet than b
- */
-static int cmp_ietfAttr(ietfAttr_t *a,ietfAttr_t *b)
-{
-       int cmp_len, len, cmp_value;
-
-       /* cannot compare OID with STRING or OCTETS attributes */
-       if (a->kind == IETF_ATTRIBUTE_OID && b->kind != IETF_ATTRIBUTE_OID)
-               return 1;
-
-       cmp_len = a->value.len - b->value.len;
-       len = (cmp_len < 0)? a->value.len : b->value.len;
-       cmp_value = memcmp(a->value.ptr, b->value.ptr, len);
-
-       return (cmp_value == 0)? cmp_len : cmp_value;
-}
-
-/**
- *  add an ietfAttribute to the chained list
- */
-static ietfAttr_t* add_ietfAttr(ietfAttr_t *attr)
-{
-       ietfAttrList_t **listp = &ietfAttributes;
-       ietfAttrList_t *list = *listp;
-       int cmp = -1;
-
-       while (list != NULL)
-       {
-               cmp = cmp_ietfAttr(attr, list->attr);
-               if (cmp <= 0)
-                       break;
-               listp = &list->next;
-               list = *listp;
-       }
-
-       if (cmp == 0)
-       {
-               /* attribute already exists, increase count */
-               free(attr);
-               list->attr->count++;
-               return list->attr;
-       }
-       else
-       {
-               ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
-
-               /* new attribute, unshare value */
-               attr->value = chunk_clone(attr->value);
-               attr->count = 1;
-               time(&attr->installed);
-
-               el->attr = attr;
-               el->next = list;
-               *listp = el;
-
-               return attr;
-       }
-}
-
-/**
- * decodes a comma separated list of group attributes
- */
-void decode_groups(char *groups, ietfAttrList_t **listp)
-{
-       if (groups == NULL)
-               return;
-
-       while (strlen(groups) > 0)
-       {
-               char *end;
-               char *next = strchr(groups, ',');
-
-               if (next == NULL)
-                  end = next = groups + strlen(groups);
-               else
-                  end = next++;
-
-               /* eat preceeding whitespace */
-               while (groups < end && *groups == ' ')
-                       groups++;
-
-               /* eat trailing whitespace */
-               while (end > groups && *(end-1) == ' ')
-                       end--;
-
-               if (groups < end)
-               {
-                       ietfAttr_t *attr   = malloc_thing(ietfAttr_t);
-                       ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
-
-                       attr->kind  = IETF_ATTRIBUTE_STRING;
-                       attr->value.ptr = groups;
-                       attr->value.len = end - groups;
-                       attr->count = 0;
-
-                       el->attr = add_ietfAttr(attr);
-                       el->next = *listp;
-                       *listp = el;
-               }
-
-               groups = next;
-       }
-}
-
-static bool same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
-{
-       return (a->kind == b->kind && a->value.len == b->value.len
-                  && memeq(a->value.ptr, b->value.ptr, b->value.len));
-}
-
-bool group_membership(const ietfAttrList_t *peer_list
-                          , const char *conn
-                          , const ietfAttrList_t *conn_list)
-{
-       if (conn_list == NULL)
-               return TRUE;
-
-       while (peer_list != NULL)
-       {
-               const ietfAttr_t *peer_attr = peer_list->attr;
-               const ietfAttrList_t *list = conn_list;
-
-               while (list != NULL)
-               {
-                       ietfAttr_t *conn_attr = list->attr;
-
-                       if (same_attribute(conn_attr, peer_attr))
-                       {
-                               DBG(DBG_CONTROL,
-                                       DBG_log("%s: peer matches group '%.*s'"
-                                               , conn
-                                               , (int)peer_attr->value.len, peer_attr->value.ptr)
-                               )
-                               return TRUE;
-                       }
-                       list = list->next;
-               }
-               peer_list = peer_list->next;
-       }
-               DBG(DBG_CONTROL,
-                       DBG_log("%s: peer doesn't match any group", conn)
-               )
-       return FALSE;
-}
-
-void unshare_ietfAttrList(ietfAttrList_t **listp)
-{
-       ietfAttrList_t *list = *listp;
-
-       while (list != NULL)
-       {
-               ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
-
-               el->attr = list->attr;
-               el->attr->count++;
-               el->next = NULL;
-               *listp = el;
-               listp = &el->next;
-               list = list->next;
-       }
-}
-
-/**
- * Parses ietfAttrSyntax
- */
-static ietfAttrList_t* parse_ietfAttrSyntax(chunk_t blob, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-
-       ietfAttrList_t *list = NULL;
-
-       parser = asn1_parser_create(ietfAttrSyntaxObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-               case IETF_ATTR_OCTETS:
-               case IETF_ATTR_OID:
-               case IETF_ATTR_STRING:
-                       {
-                               ietfAttr_t *attr   = malloc_thing(ietfAttr_t);
-                               ietfAttrList_t *el = malloc_thing(ietfAttrList_t);
-
-                               attr->kind  = (objectID - IETF_ATTR_OCTETS) / 2;
-                               attr->value = object;
-                               attr->count = 0;
-
-                               el->attr = add_ietfAttr(attr);
-                               el->next = list;
-                               list = el;
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-       parser->destroy(parser);
-       return list;
-}
-
-/**
- * Parses roleSyntax
- */
-static void parse_roleSyntax(chunk_t blob, int level0)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-
-       parser = asn1_parser_create(roleSyntaxObjects, blob);
-       parser->set_top_level(parser, level0);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               switch (objectID)
-               {
-                       default:
-                               break;
-               }
-       }
-       parser->destroy(parser);
-}
-
-/**
- *  Parses an X.509 attribute certificate
- */
-bool parse_ac(chunk_t blob, x509acert_t *ac)
-{
-       asn1_parser_t *parser;
-       chunk_t object;
-       int objectID;
-       int type = OID_UNKNOWN;
-       int extn_oid = OID_UNKNOWN;
-       bool success = FALSE;
-       bool critical;
-
-       parser = asn1_parser_create(acObjects, blob);
-
-       while (parser->iterate(parser, &objectID, &object))
-       {
-               u_int level = parser->get_level(parser)+1;
-
-               switch (objectID)
-               {
-               case AC_OBJ_CERTIFICATE:
-                       ac->certificate = object;
-                       break;
-               case AC_OBJ_CERTIFICATE_INFO:
-                       ac->certificateInfo = object;
-                       break;
-               case AC_OBJ_VERSION:
-                       ac->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
-                       DBG(DBG_PARSING,
-                               DBG_log("  v%d", ac->version);
-                       )
-                       if (ac->version != 2)
-                       {
-                               plog("v%d attribute certificates are not supported"
-                                       , ac->version);
-                               goto end;
-                       }
-                       break;
-               case AC_OBJ_HOLDER_ISSUER:
-                       ac->holderIssuer = get_directoryName(object, level, FALSE);
-                       break;
-               case AC_OBJ_HOLDER_SERIAL:
-                       ac->holderSerial = object;
-                       break;
-               case AC_OBJ_ENTITY_NAME:
-                       ac->entityName = get_directoryName(object, level, TRUE);
-                       break;
-               case AC_OBJ_ISSUER_NAME:
-                       ac->issuerName = get_directoryName(object, level, FALSE);
-                       break;
-               case AC_OBJ_SIG_ALG:
-                       ac->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case AC_OBJ_SERIAL_NUMBER:
-                       ac->serialNumber = object;
-                       break;
-               case AC_OBJ_NOT_BEFORE:
-                       ac->notBefore = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case AC_OBJ_NOT_AFTER:
-                       ac->notAfter = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
-                       break;
-               case AC_OBJ_ATTRIBUTE_TYPE:
-                       type = asn1_known_oid(object);
-                       break;
-               case AC_OBJ_ATTRIBUTE_VALUE:
-                       {
-                               switch (type) {
-                               case OID_AUTHENTICATION_INFO:
-                                       DBG(DBG_PARSING,
-                                               DBG_log("  need to parse authenticationInfo")
-                                       )
-                                       break;
-                               case OID_ACCESS_IDENTITY:
-                                       DBG(DBG_PARSING,
-                                               DBG_log("  need to parse accessIdentity")
-                                       )
-                                       break;
-                               case OID_CHARGING_IDENTITY:
-                                       ac->charging = parse_ietfAttrSyntax(object, level);
-                                       break;
-                               case OID_GROUP:
-                                       ac->groups = parse_ietfAttrSyntax(object, level);
-                                       break;
-                               case OID_ROLE:
-                                       parse_roleSyntax(object, level);
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case AC_OBJ_EXTN_ID:
-                       extn_oid = asn1_known_oid(object);
-                       break;
-               case AC_OBJ_CRITICAL:
-                       critical = object.len && *object.ptr;
-                       DBG(DBG_PARSING,
-                               DBG_log("  %s",(critical)?"TRUE":"FALSE");
-                       )
-                       break;
-               case AC_OBJ_EXTN_VALUE:
-                       {
-                               switch (extn_oid) {
-                               case OID_CRL_DISTRIBUTION_POINTS:
-                                       DBG(DBG_PARSING,
-                                               DBG_log("  need to parse crlDistributionPoints")
-                                       )
-                                       break;
-                               case OID_AUTHORITY_KEY_ID:
-                                       parse_authorityKeyIdentifier(object, level
-                                               , &ac->authKeyID, &ac->authKeySerialNumber);
-                                       break;
-                               case OID_TARGET_INFORMATION:
-                                       DBG(DBG_PARSING,
-                                               DBG_log("  need to parse targetInformation")
-                                       )
-                                       break;
-                               case OID_NO_REV_AVAIL:
-                                       ac->noRevAvail = TRUE;
-                                       break;
-                               default:
-                                       break;
-                               }
-                       }
-                       break;
-               case AC_OBJ_ALGORITHM:
-                       ac->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
-                       break;
-               case AC_OBJ_SIGNATURE:
-                       ac->signature = object;
-                       break;
-
-               default:
-                       break;
-               }
-       }
-       success = parser->success(parser);
-       time(&ac->installed);
-
-end:
-       parser->destroy(parser);
-       return success;
-}
-
-/**
- *  Release an ietfAttribute, free it if count reaches zero
- */
-static void release_ietfAttr(ietfAttr_t* attr)
-{
-       if (--attr->count == 0)
-       {
-               ietfAttrList_t **plist = &ietfAttributes;
-               ietfAttrList_t *list = *plist;
-
-               while (list->attr != attr)
-               {
-                       plist = &list->next;
-                       list = *plist;
-               }
-               *plist = list->next;
-
-               free(attr->value.ptr);
-               free(attr);
-               free(list);
-       }
-}
-
-/**
- *  Free an ietfAttrList
- */
-void free_ietfAttrList(ietfAttrList_t* list)
-{
-       while (list != NULL)
-       {
-               ietfAttrList_t *el = list;
-
-               release_ietfAttr(el->attr);
-               list = list->next;
-               free(el);
-       }
-}
-
-/**
  *  Free a X.509 attribute certificate
  */
 void free_acert(x509acert_t *ac)
 {
-       if (ac != NULL)
+       if (ac)
        {
-               free_ietfAttrList(ac->charging);
-               free_ietfAttrList(ac->groups);
-               free(ac->certificate.ptr);
+               DESTROY_IF(ac->ac);
                free(ac);
        }
 }
@@ -656,7 +69,9 @@ static void free_first_acert(void)
 void free_acerts(void)
 {
        while (x509acerts != NULL)
+       {
                free_first_acert();
+       }
 }
 
 /**
@@ -664,25 +79,30 @@ void free_acerts(void)
  */
 x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial)
 {
-       x509acert_t *ac = x509acerts;
+       x509acert_t *x509ac = x509acerts;
        x509acert_t *prev_ac = NULL;
 
-       while (ac != NULL)
+       while (x509ac != NULL)
        {
-               if (same_dn(issuer, ac->holderIssuer) &&
-                       chunk_equals(serial, ac->holderSerial))
+               ac_t *ac = (ac_t*)x509ac->ac;
+               identification_t *holderIssuer = ac->get_holderIssuer(ac);
+               chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer);
+               chunk_t holderSerial = ac->get_holderSerial(ac);
+
+               if (same_dn(issuer, holderIssuer_dn) &&
+                       chunk_equals(serial, holderSerial))
                {
-                       if (ac!= x509acerts)
+                       if (x509ac!= x509acerts)
                        {
                                /* bring the certificate up front */
-                               prev_ac->next = ac->next;
-                               ac->next = x509acerts;
-                               x509acerts = ac;
+                               prev_ac->next = x509ac->next;
+                               x509ac->next = x509acerts;
+                               x509acerts = x509ac;
                        }
-                       return ac;
+                       return x509ac;
                }
-               prev_ac = ac;
-               ac = ac->next;
+               prev_ac = x509ac;
+               x509ac = x509ac->next;
        }
        return NULL;
 }
@@ -690,13 +110,19 @@ x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial)
 /**
  *  Add a X.509 attribute certificate to the chained list
  */
-static void add_acert(x509acert_t *ac)
+static void add_acert(x509acert_t *x509ac)
 {
-       x509acert_t *old_ac = get_x509acert(ac->holderIssuer, ac->holderSerial);
-
+       certificate_t *cert_ac = x509ac->ac;
+       ac_t *ac = (ac_t*)cert_ac;
+       identification_t *holderIssuer = ac->get_holderIssuer(ac);
+       chunk_t holderIssuer_dn = holderIssuer->get_encoding(holderIssuer);
+       chunk_t holderSerial = ac->get_serial(ac);
+       x509acert_t *old_ac;
+
+       old_ac = get_x509acert(holderIssuer_dn, holderSerial);
        if (old_ac != NULL)
        {
-               if (ac->notBefore >old_ac->notBefore)
+               if (cert_ac->is_newer(cert_ac, old_ac->ac))
                {
                        /* delete the old attribute cert */
                        free_first_acert();
@@ -709,70 +135,46 @@ static void add_acert(x509acert_t *ac)
                        DBG(DBG_CONTROL,
                                DBG_log("attribute cert is not newer - existing cert kept");
                        )
-                       free_acert(ac);
+                       free_acert(x509ac);
                        return;
                }
        }
        plog("attribute cert added");
 
        /* insert new attribute cert at the root of the chain */
-       ac->next = x509acerts;
-       x509acerts = ac;
-}
-
-/**
- * Verify the validity of an attribute certificate by
- * checking the notBefore and notAfter dates
- */
-static err_t check_ac_validity(const x509acert_t *ac)
-{
-       time_t current_time;
-
-       time(&current_time);
-       DBG(DBG_CONTROL | DBG_PARSING,
-               DBG_log("  not before  : %T", &ac->notBefore, TRUE);
-               DBG_log("  current time: %T", &current_time, TRUE);
-               DBG_log("  not after   : %T", &ac->notAfter, TRUE);
-       )
-
-       if (current_time < ac->notBefore)
-               return "attribute certificate is not valid yet";
-       if (current_time > ac->notAfter)
-               return "attribute certificate has expired";
-       else
-               return NULL;
+       x509ac->next = x509acerts;
+       x509acerts = x509ac;
 }
 
 /**
  * verifies a X.509 attribute certificate
  */
-bool verify_x509acert(x509acert_t *ac, bool strict)
+bool verify_x509acert(x509acert_t *x509ac, bool strict)
 {
-       u_char buf[BUF_LEN];
+       certificate_t *cert_ac = x509ac->ac;
+       ac_t *ac = (ac_t*)cert_ac;
+       identification_t *subject = cert_ac->get_subject(cert_ac);
+       identification_t *issuer = cert_ac->get_issuer(cert_ac);
+       chunk_t issuer_dn = issuer->get_encoding(issuer);
+       chunk_t authKeyID = ac->get_authKeyIdentifier(ac);
        x509cert_t *aacert;
-       err_t ugh = NULL;
-       time_t valid_until = ac->notAfter;
+       time_t valid_until;
 
        DBG(DBG_CONTROL,
-               dntoa(buf, BUF_LEN, ac->entityName);
-               DBG_log("holder: '%s'",buf);
-               dntoa(buf, BUF_LEN, ac->issuerName);
-               DBG_log("issuer: '%s'",buf);
+               DBG_log("holder: '%Y'", subject);
+               DBG_log("issuer: '%Y'", issuer);
        )
 
-       ugh = check_ac_validity(ac);
-
-       if (ugh != NULL)
+       if (!cert_ac->get_validity(cert_ac, NULL, NULL, &valid_until))
        {
-               plog("%s", ugh);
                return FALSE;
        }
        DBG(DBG_CONTROL,
-               DBG_log("attribute certificate is valid")
+               DBG_log("attribute certificate is valid until %T", &valid_until, TRUE)
        )
 
        lock_authcert_list("verify_x509acert");
-       aacert = get_authcert(ac->issuerName, ac->authKeyID, AUTH_AA);
+       aacert = get_authcert(issuer_dn, authKeyID, X509_AA);
        unlock_authcert_list("verify_x509acert");
 
        if (aacert == NULL)
@@ -784,8 +186,7 @@ bool verify_x509acert(x509acert_t *ac, bool strict)
                DBG_log("issuer aacert found")
        )
 
-       if (!x509_check_signature(ac->certificateInfo, ac->signature, ac->algorithm,
-                                                         aacert->cert))
+       if (!cert_ac->issued_by(cert_ac, aacert->cert))
        {
                plog("attribute certificate signature is invalid");
                return FALSE;
@@ -798,6 +199,31 @@ bool verify_x509acert(x509acert_t *ac, bool strict)
 }
 
 /**
+ * Check if at least one peer attribute matches a connection attribute
+ */
+bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn,
+                                                       ietf_attributes_t *conn_attributes)
+{
+       bool match;
+
+       if (conn_attributes == NULL)
+       {
+               return TRUE;
+       }
+
+       match = conn_attributes->matches(conn_attributes, peer_attributes);
+       DBG(DBG_CONTROL,
+               DBG_log("%s: peer with attributes '%s' is %sa member of the groups '%s'",
+                               conn,
+                               peer_attributes->get_string(peer_attributes),
+                               match ? "" : "not ",
+                               conn_attributes->get_string(conn_attributes))
+       )
+       return match;
+
+}
+
+/**
  * Loads X.509 attribute certificates
  */
 void load_acerts(void)
@@ -840,141 +266,82 @@ void load_acerts(void)
 }
 
 /**
- * lists group attributes separated by commas on a single line
- */
-void format_groups(const ietfAttrList_t *list, char *buf, int len)
-{
-       bool first_group = TRUE;
-
-       while (list != NULL && len > 0)
-       {
-               ietfAttr_t *attr = list->attr;
-
-               if (attr->kind == IETF_ATTRIBUTE_OCTETS
-               ||  attr->kind == IETF_ATTRIBUTE_STRING)
-               {
-                       int written = snprintf(buf, len, "%s%.*s"
-                                                       , (first_group)? "" : ", "
-                                                       , (int)attr->value.len, attr->value.ptr);
-
-                       first_group = FALSE;
-
-                       /* return value of snprintf() up to glibc 2.0.6 */
-                       if (written < 0)
-                               break;
-
-                       buf += written;
-                       len -= written;
-               }
-               list = list->next;
-       }
-}
-
-/**
  *  list all X.509 attribute certificates in the chained list
  */
 void list_acerts(bool utc)
 {
-       x509acert_t *ac = x509acerts;
+       x509acert_t *x509ac = x509acerts;
        time_t now;
 
        /* determine the current time */
        time(&now);
 
-       if (ac != NULL)
+       if (x509ac)
        {
                whack_log(RC_COMMENT, " ");
                whack_log(RC_COMMENT, "List of X.509 Attribute Certificates:");
                whack_log(RC_COMMENT, " ");
        }
 
-       while (ac != NULL)
+       while (x509ac)
        {
-               u_char buf[BUF_LEN];
+               certificate_t *cert_ac = x509ac->ac;
+               ac_t *ac = (ac_t*)cert_ac;
+               identification_t *entityName, *holderIssuer, *issuer;
+               chunk_t holderSerial, serial, authKeyID;
+               time_t notBefore, notAfter;
+               ietf_attributes_t *groups;
 
-               whack_log(RC_COMMENT, "%T", &ac->installed, utc);
-               if (ac->entityName.ptr != NULL)
-               {
-                       dntoa(buf, BUF_LEN, ac->entityName);
-                       whack_log(RC_COMMENT, "       holder:   '%s'", buf);
-               }
-               if (ac->holderIssuer.ptr != NULL)
-               {
-                       dntoa(buf, BUF_LEN, ac->holderIssuer);
-                       whack_log(RC_COMMENT, "       hissuer:  '%s'", buf);
-               }
-               if (ac->holderSerial.ptr != NULL)
+
+               whack_log(RC_COMMENT, "%T", &x509ac->installed, utc);
+
+               entityName = cert_ac->get_subject(cert_ac);
+               if (entityName)
                {
-                       datatot(ac->holderSerial.ptr, ac->holderSerial.len, ':'
-                               , buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       hserial:   %s", buf);
+                       whack_log(RC_COMMENT, "       holder:   '%Y'", entityName);
                }
-               if (ac->groups != NULL)
+
+               holderIssuer = ac->get_holderIssuer(ac);
+               if (holderIssuer)
                {
-                       format_groups(ac->groups, buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       groups:    %s", buf);
+                       whack_log(RC_COMMENT, "       hissuer:  '%Y'", holderIssuer);
                }
-               dntoa(buf, BUF_LEN, ac->issuerName);
-               whack_log(RC_COMMENT, "       issuer:   '%s'", buf);
-               datatot(ac->serialNumber.ptr, ac->serialNumber.len, ':'
-                       , buf, BUF_LEN);
-               whack_log(RC_COMMENT, "       serial:    %s", buf);
-               whack_log(RC_COMMENT, "       validity:  not before %T %s",
-                               &ac->notBefore, utc,
-                               (ac->notBefore < now)?"ok":"fatal (not valid yet)");
-               whack_log(RC_COMMENT, "                  not after  %T %s",
-                               &ac->notAfter, utc,
-                               check_expiry(ac->notAfter, ACERT_WARNING_INTERVAL, TRUE));
-               if (ac->authKeyID.ptr != NULL)
+
+               holderSerial = ac->get_holderSerial(ac);
+               if (holderSerial.ptr)
                {
-                       datatot(ac->authKeyID.ptr, ac->authKeyID.len, ':'
-                               , buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       authkey:   %s", buf);
+                       whack_log(RC_COMMENT, "       hserial:   %#B", &holderSerial);
                }
-               if (ac->authKeySerialNumber.ptr != NULL)
+
+               groups = ac->get_groups(ac);            
+               if (groups)
                {
-                       datatot(ac->authKeySerialNumber.ptr, ac->authKeySerialNumber.len, ':'
-                               , buf, BUF_LEN);
-                       whack_log(RC_COMMENT, "       aserial:   %s", buf);
+                       whack_log(RC_COMMENT, "       groups:    %s",
+                                       groups->get_string(groups));
+                       groups->destroy(groups);
                }
 
-               ac = ac->next;
-       }
-}
+               issuer = cert_ac->get_issuer(cert_ac);
+               whack_log(RC_COMMENT, "       issuer:   '%Y'", issuer);
 
-/**
- *  list all group attributes in alphabetical order
- */
-void list_groups(bool utc)
-{
-       ietfAttrList_t *list = ietfAttributes;
+               serial = ac->get_serial(ac);
+               whack_log(RC_COMMENT, "       serial:    %#B", &serial);
 
-       if (list != NULL)
-       {
-               whack_log(RC_COMMENT, " ");
-               whack_log(RC_COMMENT, "List of Group Attributes:");
-               whack_log(RC_COMMENT, " ");
-       }
-
-       while (list != NULL)
-       {
-               ietfAttr_t *attr = list->attr;
-
-               whack_log(RC_COMMENT, "%T, count: %d", &attr->installed, utc, attr->count);
+               cert_ac->get_validity(cert_ac, &now, &notBefore, &notAfter);
+               whack_log(RC_COMMENT, "       validity:  not before %T %s",
+                               &notBefore, utc,
+                               (notBefore < now)?"ok":"fatal (not valid yet)");
+               whack_log(RC_COMMENT, "                  not after  %T %s",
+                               &notAfter, utc,
+                               check_expiry(notAfter, ACERT_WARNING_INTERVAL, TRUE));
 
-               switch (attr->kind)
+               authKeyID = ac->get_authKeyIdentifier(ac);
+               if (authKeyID.ptr)
                {
-               case IETF_ATTRIBUTE_OCTETS:
-               case IETF_ATTRIBUTE_STRING:
-                       whack_log(RC_COMMENT, "       %.*s", (int)attr->value.len, attr->value.ptr);
-                       break;
-               case IETF_ATTRIBUTE_OID:
-                       whack_log(RC_COMMENT, "       OID");
-                       break;
-               default:
-                       break;
+                       whack_log(RC_COMMENT, "       authkey:   %#B", &authKeyID);
                }
 
-               list = list->next;
+               x509ac = x509ac->next;
        }
 }
+
index bee0161..d1feb55 100644 (file)
@@ -1,6 +1,7 @@
 /* Support of X.509 attribute certificates
  * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
  * Copyright (C) 2003 Martin Berner, Lukas Suter
+ * Copyright (C) 2009 Andreas Steffen
 
  *
  * This program is free software; you can redistribute it and/or modify it
 #ifndef _AC_H
 #define _AC_H
 
-/* definition of ietfAttribute kinds */
-
-typedef enum {
-       IETF_ATTRIBUTE_OCTETS =     0,
-       IETF_ATTRIBUTE_OID =        1,
-       IETF_ATTRIBUTE_STRING =     2
-} ietfAttribute_t;
-
-/* access structure for an ietfAttribute */
-
-typedef struct ietfAttr ietfAttr_t;
-
-struct ietfAttr {
-  time_t           installed;
-  int              count;
-  ietfAttribute_t  kind;
-  chunk_t          value;
-};
-
-typedef struct ietfAttrList ietfAttrList_t;
-
-struct ietfAttrList {
-  ietfAttrList_t   *next;
-  ietfAttr_t       *attr;
-};
+#include <time.h>
 
+#include <credentials/certificates/certificate.h>
+#include <credentials/ietf_attributes/ietf_attributes.h>
 
 /* access structure for an X.509 attribute certificate */
 
 typedef struct x509acert x509acert_t;
 
 struct x509acert {
-  x509acert_t    *next;
-  time_t         installed;
-  chunk_t        certificate;
-  chunk_t          certificateInfo;
-  u_int              version;
-                               /*   holder */
-                               /*     baseCertificateID */
-  chunk_t                holderIssuer;
-  chunk_t                holderSerial;
-  chunk_t                entityName;
-                               /*   v2Form */
-  chunk_t              issuerName;
-                               /*   signature */
-  int                  sigAlg;
-  chunk_t            serialNumber;
-                               /*   attrCertValidityPeriod */
-  time_t               notBefore;
-  time_t               notAfter;
-                               /*   attributes */
-  ietfAttrList_t       *charging;
-  ietfAttrList_t       *groups;
-                               /*   extensions */
-  chunk_t              authKeyID;
-  chunk_t              authKeySerialNumber;
-  bool                 noRevAvail;
-                               /* signatureAlgorithm */
-  int                algorithm;
-  chunk_t          signature;
+       certificate_t *ac;
+       x509acert_t    *next;
+       time_t         installed;
 };
 
-/* used for initialization */
-extern const x509acert_t empty_ac;
-
-extern void unshare_ietfAttrList(ietfAttrList_t **listp);
-extern void free_ietfAttrList(ietfAttrList_t *list);
-extern void decode_groups(char *groups, ietfAttrList_t **listp);
-extern bool group_membership(const ietfAttrList_t *my_list
-       , const char *conn, const ietfAttrList_t *conn_list);
-extern bool parse_ac(chunk_t blob, x509acert_t *ac);
 extern bool verify_x509acert(x509acert_t *ac, bool strict);
+extern bool match_group_membership(ietf_attributes_t *peer_attributes, char *conn,
+                                                                  ietf_attributes_t *conn_attributes);
 extern x509acert_t* get_x509acert(chunk_t issuer, chunk_t serial);
 extern void load_acerts(void);
 extern void free_acert(x509acert_t *ac);
 extern void free_acerts(void);
 extern void list_acerts(bool utc);
-extern void list_groups(bool utc);
-extern void format_groups(const ietfAttrList_t *list, char *buf, int len);
-
 
 #endif /* _AH_H */
index 8a90e05..b8b9aac 100644 (file)
@@ -40,6 +40,7 @@
  */
 static cert_t *builder_load_cert(certificate_type_t type, va_list args)
 {
+       x509_flag_t flags = 0;
        chunk_t blob = chunk_empty;
        bool pgp = FALSE;
 
@@ -53,6 +54,9 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
                        case BUILD_BLOB_ASN1_DER:
                                blob = va_arg(args, chunk_t);
                                continue;
+                       case BUILD_X509_FLAG:
+                               flags |= va_arg(args, x509_flag_t);
+                               continue;
                        case BUILD_END:
                                break;
                        default:
@@ -85,6 +89,7 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
                        x509cert->cert = lib->creds->create(lib->creds,
                                                                                CRED_CERTIFICATE, CERT_X509,
                                                                                BUILD_BLOB_ASN1_DER, blob,
+                                                                               BUILD_X509_FLAG, flags,
                                                                                BUILD_END);
                        if (x509cert->cert)
                        {
@@ -128,9 +133,12 @@ static x509acert_t *builder_load_ac(certificate_type_t type, va_list args)
        if (blob.ptr)
        {
                ac = malloc_thing(x509acert_t);
-               *ac = empty_ac;
-               if (parse_ac(chunk_clone(blob), ac) &&
-                       verify_x509acert(ac, FALSE))
+               ac->next = NULL;
+               ac->installed = UNDEFINED_TIME;
+               ac->ac = lib->creds->create(lib->creds,
+                                                                       CRED_CERTIFICATE, CERT_X509_AC,
+                                                                       BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+               if (ac->ac && verify_x509acert(ac, FALSE))
                {
                        return ac;
                }
index bc6bfe9..816e710 100644 (file)
@@ -81,7 +81,7 @@ bool trusted_ca(chunk_t a, chunk_t b, int *pathlen)
                chunk_t issuer_dn;
                x509cert_t *cacert;
 
-               cacert = get_authcert(a, chunk_empty, AUTH_CA);
+               cacert = get_authcert(a, chunk_empty, X509_CA);
                if (cacert == NULL)
                {
                        break;
@@ -180,7 +180,7 @@ void free_authcerts(void)
 /*
  *  get a X.509 authority certificate with a given subject or keyid
  */
-x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, u_char auth_flags)
+x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, x509_flag_t auth_flags)
 {
        x509cert_t *cert, *prev_cert = NULL;
 
@@ -193,11 +193,12 @@ x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, u_char auth_flags)
        for (cert = x509authcerts; cert != NULL; prev_cert = cert, cert = cert->next)
        {
                certificate_t *certificate = cert->cert;
+               x509_t *x509 = (x509_t*)certificate;
                identification_t *cert_subject;
                chunk_t cert_subject_dn;
 
                /* skip non-matching types of authority certificates */
-               if (!(cert->authority_flags & auth_flags))
+               if (!(x509->get_flags(x509) & auth_flags))
                {
                        continue;
                }
@@ -205,7 +206,6 @@ x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, u_char auth_flags)
                /* compare the keyid with the certificate's subjectKeyIdentifier */
                if (keyid.ptr)
                {
-                       x509_t *x509 = (x509_t*)certificate;
                        chunk_t subjectKeyId;
 
                        subjectKeyId = x509->get_subjectKeyIdentifier(x509);
@@ -239,7 +239,7 @@ x509cert_t* get_authcert(chunk_t subject, chunk_t keyid, u_char auth_flags)
 /*
  * add an authority certificate to the chained list
  */
-x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags)
+x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags)
 {
        certificate_t *certificate = cert->cert;
        x509_t *x509 = (x509_t*)certificate;
@@ -247,9 +247,6 @@ x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags)
        chunk_t cert_subject_dn = cert_subject->get_encoding(cert_subject);
        x509cert_t *old_cert;
 
-       /* set authority flags */
-       cert->authority_flags |= auth_flags;
-
        lock_authcert_list("add_authcert");
 
        old_cert = get_authcert(cert_subject_dn, 
@@ -259,8 +256,6 @@ x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags)
        {
                if (certificate->equals(certificate, old_cert->cert))
                {
-                       /* cert is already present, just add additional authority flags */
-                       old_cert->authority_flags |= cert->authority_flags;
                        DBG(DBG_CONTROL | DBG_PARSING ,
                                DBG_log("  authcert is already present and identical")
                        )
@@ -293,7 +288,7 @@ x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags)
 /*
  *  Loads authority certificates
  */
-void load_authcerts(const char *type, const char *path, u_char auth_flags)
+void load_authcerts(const char *type, const char *path, x509_flag_t auth_flags)
 {
        struct dirent **filelist;
        u_char buf[BUF_LEN];
@@ -320,9 +315,10 @@ void load_authcerts(const char *type, const char *path, u_char auth_flags)
                        {
                                cert_t cert;
 
-                               if (load_cert(filelist[n]->d_name, type, &cert))
+                               if (load_cert(filelist[n]->d_name, type, auth_flags, &cert))
+                               {
                                        add_authcert(cert.u.x509, auth_flags);
-
+                               }
                                free(filelist[n]);
                        }
                        free(filelist);
@@ -335,7 +331,7 @@ void load_authcerts(const char *type, const char *path, u_char auth_flags)
 /*
  *  list all X.509 authcerts with given auth flags in a chained list
  */
-void list_authcerts(const char *caption, u_char auth_flags, bool utc)
+void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc)
 {
        lock_authcert_list("list_authcerts");
        list_x509cert_chain(caption, x509authcerts, auth_flags, utc);
@@ -426,7 +422,7 @@ bool trust_authcert_candidate(const x509cert_t *cert, const x509cert_t *alt_chai
                else
                {
                        /* search in trusted chain */
-                       authcert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
+                       authcert = get_authcert(issuer_dn, authKeyID, X509_CA);
 
                        if (authcert != NULL)
                        {
@@ -670,7 +666,7 @@ void add_ca_info(const whack_message_t *msg)
                unlock_ca_info_list("add_ca_info");
 
                /* add cacert to list of authcerts */
-               cacert = add_authcert(cacert, AUTH_CA);
+               cacert = add_authcert(cacert, X509_CA);
                if (!cached_cert && sc != NULL)
                {
                        if (sc->last_cert.type == CERT_X509_SIGNATURE)
index eadb96d..8c7627d 100644 (file)
 
 #define MAX_CA_PATH_LEN         7
 
-/* authority flags */
-
-#define AUTH_NONE       0x00    /* no authorities */
-#define AUTH_CA         0x01    /* certification authority */
-#define AUTH_AA         0x02    /* authorization authority */
-#define AUTH_OCSP       0x04    /* ocsp signing authority */
-
 /* CA info structures */
 
 typedef struct ca_info ca_info_t;
@@ -47,17 +40,17 @@ struct ca_info {
 };
 
 extern bool trusted_ca(chunk_t a, chunk_t b, int *pathlen);
-extern bool match_requested_ca(generalName_t *requested_ca
-       , chunk_t our_ca, int *our_pathlen);
+extern bool match_requested_ca(generalName_t *requested_ca, chunk_t our_ca,
+                                                          int *our_pathlen);
 extern x509cert_t* get_authcert(chunk_t subject, chunk_t keyid,
-                                                               u_char auth_flags);
-extern void load_authcerts(const char *type, const char *path
-       , u_char auth_flags);
-extern x509cert_t* add_authcert(x509cert_t *cert, u_char auth_flags);
+                                                               x509_flag_t auth_flags);
+extern void load_authcerts(const char *type, const char *path,
+                                                  x509_flag_t auth_flags);
+extern x509cert_t* add_authcert(x509cert_t *cert, x509_flag_t auth_flags);
 extern void free_authcerts(void);
-extern void list_authcerts(const char *caption, u_char auth_flags, bool utc);
-extern bool trust_authcert_candidate(const x509cert_t *cert
-       , const x509cert_t *alt_chain);
+extern void list_authcerts(const char *caption, x509_flag_t auth_flags, bool utc);
+extern bool trust_authcert_candidate(const x509cert_t *cert,
+                                                                        const x509cert_t *alt_chain);
 extern ca_info_t* get_ca_info(chunk_t name, chunk_t keyid);
 extern bool find_ca_info_by_name(const char *name, bool delete);
 extern void add_ca_info(const whack_message_t *msg);
index cdf567e..456a45f 100644 (file)
@@ -162,12 +162,14 @@ private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
 /**
  *  Loads a X.509 or OpenPGP certificate
  */
-bool load_cert(char *filename, const char *label, cert_t *out)
+bool load_cert(char *filename, const char *label, x509_flag_t flags, cert_t *out)
 {
        cert_t *cert;
 
        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT,
-                                                         BUILD_FROM_FILE, filename, BUILD_END);
+                                                         BUILD_FROM_FILE, filename,
+                                                         BUILD_X509_FLAG, flags,
+                                                         BUILD_END);
        if (cert)
        {
                /* the API passes an empty cert_t, we move over and free the built one */
@@ -186,7 +188,7 @@ bool load_host_cert(char *filename, cert_t *cert)
 {
        char *path = concatenate_paths(HOST_CERT_PATH, filename);
 
-       return load_cert(path, "host", cert);
+       return load_cert(path, "host", X509_NONE, cert);
 }
 
 /**
@@ -196,7 +198,7 @@ bool load_ca_cert(char *filename, cert_t *cert)
 {
        char *path = concatenate_paths(CA_CERT_PATH, filename);
 
-       return load_cert(path, "CA", cert);
+       return load_cert(path, "CA", X509_NONE, cert);
 }
 
 /**
index 1bd03ed..faf820d 100644 (file)
@@ -66,7 +66,8 @@ extern public_key_t* cert_get_public_key(const cert_t cert);
 extern chunk_t cert_get_encoding(cert_t cert);
 extern private_key_t* load_private_key(char* filename, prompt_pass_t *pass,
                                                                           key_type_t type);
-extern bool load_cert(char *filename, const char *label, cert_t *cert);
+extern bool load_cert(char *filename, const char *label, x509_flag_t flags,
+                                         cert_t *cert);
 extern bool load_host_cert(char *filename, cert_t *cert);
 extern bool load_ca_cert(char *filename, cert_t *cert);
 extern bool same_cert(const cert_t *a, const cert_t *b);
index d375e49..e1a28ca 100644 (file)
@@ -30,6 +30,7 @@
 #include <freeswan.h>
 #include "kameipsec.h"
 
+#include <credentials/certificates/ac.h>
 #include <credentials/keys/private_key.h>
 
 #include "constants.h"
@@ -336,11 +337,11 @@ void delete_connection(connection_t *c, bool relations)
        free_id_content(&c->spd.this.id);
        free(c->spd.this.updown);
        free(c->spd.this.ca.ptr);
-       free_ietfAttrList(c->spd.this.groups);
+       DESTROY_IF(c->spd.this.groups);
        free_id_content(&c->spd.that.id);
        free(c->spd.that.updown);
        free(c->spd.that.ca.ptr);
-       free_ietfAttrList(c->spd.that.groups);
+       DESTROY_IF(c->spd.that.groups);
        free_generalNames(c->requested_ca, TRUE);
        gw_delref(&c->gw_info);
 
@@ -812,7 +813,7 @@ static bool extract_end(struct end *dst, const whack_end_t *src,
        dst->ca = chunk_empty;
 
        /* decode CA distinguished name, if any */
-       if (src->ca != NULL)
+       if (src->ca)
        {
                if streq(src->ca, "%same")
                        same_ca = TRUE;
@@ -837,7 +838,10 @@ static bool extract_end(struct end *dst, const whack_end_t *src,
        dst->has_id_wildcards = id_count_wildcards(&dst->id) > 0;
 
        /* decode group attributes, if any */
-       decode_groups(src->groups, &dst->groups);
+       if (src->groups)
+       {
+               dst->groups = ietf_attributes_create_from_string(src->groups);
+       }
 
        /* the rest is simple copying of corresponding fields */
        dst->host_addr = src->host_addr;
@@ -1261,8 +1265,14 @@ static connection_t *instantiate(connection_t *c,
                d->spd.that.has_id_wildcards = FALSE;
        }
        unshare_connection_strings(d);
-       unshare_ietfAttrList(&d->spd.this.groups);
-       unshare_ietfAttrList(&d->spd.that.groups);
+       if (d->spd.this.groups)
+       {
+               d->spd.this.groups = d->spd.this.groups->get_ref(d->spd.this.groups);
+       }
+       if (d->spd.that.groups)
+       {
+               d->spd.that.groups = d->spd.that.groups->get_ref(d->spd.that.groups);
+       }
        d->kind = CK_INSTANCE;
 
        passert(oriented(*d));
@@ -1519,7 +1529,9 @@ connection_t *find_connection_for_clients(struct spd_route **srp,
        for (c = connections; c != NULL; c = c->ac_next)
        {
                if (c->kind == CK_GROUP)
+               {
                        continue;
+               }
 
                for (sr = &c->spd; best!=c && sr; sr = sr->next)
                {
@@ -1727,7 +1739,9 @@ bool orient(connection_t *c)
                        for (p = interfaces; p != NULL; p = p->next)
                        {
                                if (p->ike_float)
+                               {
                                        continue;
+                               }
 
                                for (;;)
                                {
@@ -3036,11 +3050,17 @@ connection_t *route_owner(connection_t *c, struct spd_route **srp,
                        for (src = &c->spd; src; src=src->next)
                        {
                                if (!samesubnet(&src->that.client, &srd->that.client))
+                               {
                                        continue;
+                               }
                                if (src->that.protocol != srd->that.protocol)
+                               {
                                        continue;
+                               }
                                if (src->that.port != srd->that.port)
+                               {
                                        continue;
+                               }
                                passert(oriented(*d));
                                if (srd->routing > best_routing)
                                {
@@ -3050,11 +3070,17 @@ connection_t *route_owner(connection_t *c, struct spd_route **srp,
                                }
 
                                if (!samesubnet(&src->this.client, &srd->this.client))
+                               {
                                        continue;
+                               }
                                if (src->this.protocol != srd->this.protocol)
+                               {
                                        continue;
+                               }
                                if (src->this.port != srd->this.port)
+                               {
                                        continue;
+                               }
                                if (srd->routing > best_erouting)
                                {
                                        best_ero = d;
@@ -3332,11 +3358,15 @@ connection_t *refine_host_connection(const struct state *st,
 
                        /* do we have a match? */
                        if (!match)
+                       {
                                continue;
+                       }
 
                        /* ignore group connections */
                        if (d->policy & POLICY_GROUP)
+                       {
                                continue;
+                       }
 
                        if (c->spd.that.host_port != d->spd.that.host_port
                        && d->kind == CK_INSTANCE)
@@ -3354,12 +3384,17 @@ connection_t *refine_host_connection(const struct state *st,
                                        const chunk_t *dpsk = get_preshared_secret(d);
 
                                        if (dpsk == NULL)
+                                       {
                                                continue;       /* no secret */
-
+                                       }
                                        if (psk != dpsk)
+                                       {
                                                if (psk->len != dpsk->len
                                                || memcmp(psk->ptr, dpsk->ptr, psk->len) != 0)
+                                               {
                                                        continue;   /* different secret */
+                                               }
+                                       }
                                }
                                break;
 
@@ -3374,7 +3409,9 @@ connection_t *refine_host_connection(const struct state *st,
                                .*/
                                if (d->spd.this.sc == NULL              /* no smartcard */
                                && get_private_key(d) == NULL)      /* no private key */
+                               {
                                        continue;
+                               }
                                break;
 
                        default:
@@ -3488,7 +3525,7 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
                                                        const u_int8_t peer_protocol,
                                                        const u_int16_t peer_port,
                                                        chunk_t peer_ca,
-                                                       const ietfAttrList_t *peer_list)
+                                                       ietf_attributes_t *peer_attributes)
 {
        connection_t *d;
        connection_t *best = NULL;
@@ -3502,20 +3539,26 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
                struct spd_route *sr;
 
                if (d->policy & POLICY_GROUP)
+               {
                        continue;
+               }
 
                if (!(same_id(&c->spd.this.id, &d->spd.this.id)
                && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
                && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
-               && group_membership(peer_list, d->name, d->spd.that.groups)))
+               && match_group_membership(peer_attributes, d->name, d->spd.that.groups)))
+               {
                        continue;
+               }
 
                /* compare protocol and ports */
                if (d->spd.this.protocol != our_protocol
                ||  d->spd.this.port != our_port
                ||  d->spd.that.protocol != peer_protocol
                || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
+               {
                        continue;
+               }
 
                /* non-Opportunistic case:
                 * our_client must match.
@@ -3552,29 +3595,38 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
 #endif /* DEBUG */
 
                        if (!samesubnet(&sr->this.client, our_net))
+                       {
                                continue;
-
+                       }
                        if (sr->that.has_client)
                        {
                                if (sr->that.has_client_wildcard)
                                {
                                        if (!subnetinsubnet(peer_net, &sr->that.client))
+                                       {
                                                continue;
+                                       }
                                }
                                else
                                {
                                        if (!samesubnet(&sr->that.client, peer_net) && !is_virtual_connection(d))
+                                       {
                                                continue;
+                                       }
                                        if (is_virtual_connection(d)
                                        && (!is_virtual_net_allowed(d, peer_net, &c->spd.that.host_addr)
                                                || is_virtual_net_used(peer_net, peer_id?peer_id:&c->spd.that.id)))
-                                                       continue;
+                                       {
+                                               continue;
+                                       }
                                }
                        }
                        else
                        {
                                if (!peer_net_is_host)
+                               {
                                        continue;
+                               }
                        }
 
                        /* We've run the gauntlet -- success:
@@ -3616,7 +3668,7 @@ static connection_t *fc_try_oppo(const connection_t *c,
                                                                 const u_int8_t peer_protocol,
                                                                 const u_int16_t peer_port,
                                                                 chunk_t peer_ca,
-                                                                const ietfAttrList_t *peer_list)
+                                                                ietf_attributes_t *peer_attributes)
 {
        connection_t *d;
        connection_t *best = NULL;
@@ -3629,20 +3681,25 @@ static connection_t *fc_try_oppo(const connection_t *c,
                policy_prio_t prio;
 
                if (d->policy & POLICY_GROUP)
+               {
                        continue;
-
+               }
                if (!(same_id(&c->spd.this.id, &d->spd.this.id)
                && match_id(&c->spd.that.id, &d->spd.that.id, &wildcards)
                && trusted_ca(peer_ca, d->spd.that.ca, &pathlen)
-               && group_membership(peer_list, d->name, d->spd.that.groups)))
+               && match_group_membership(peer_attributes, d->name, d->spd.that.groups)))
+               {
                        continue;
+               }
 
                /* compare protocol and ports */
                if (d->spd.this.protocol != our_protocol
                ||  d->spd.this.port != our_port
                ||  d->spd.that.protocol != peer_protocol
                || (d->spd.that.port != peer_port && !d->spd.that.has_port_wildcard))
+               {
                        continue;
+               }
 
                /* Opportunistic case:
                 * our_net must be inside d->spd.this.client
@@ -3670,7 +3727,9 @@ static connection_t *fc_try_oppo(const connection_t *c,
 
                        if (!subnetinsubnet(our_net, &sr->this.client)
                        || !subnetinsubnet(peer_net, &sr->that.client))
+                       {
                                continue;
+                       }
 
                        /* The connection is feasible, but we continue looking for the best.
                         * The highest priority wins, implementing eroute-like rule.
@@ -3710,21 +3769,25 @@ static connection_t *fc_try_oppo(const connection_t *c,
 /*
  * get the peer's CA and group attributes
  */
-chunk_t get_peer_ca_and_groups(connection_t *c, const ietfAttrList_t **peer_list)
+chunk_t get_peer_ca_and_groups(connection_t *c, ietf_attributes_t **peer_attributes)
 {
        struct state *p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);
 
-       *peer_list = NULL;
+       *peer_attributes = NULL;
 
        if (p1st != NULL
        &&  p1st->st_peer_pubkey != NULL
        &&  p1st->st_peer_pubkey->issuer.ptr != NULL)
        {
-               x509acert_t *ac = get_x509acert(p1st->st_peer_pubkey->issuer
-                                                                         , p1st->st_peer_pubkey->serial);;
+               x509acert_t *x509ac = get_x509acert(p1st->st_peer_pubkey->issuer,
+                                                                                       p1st->st_peer_pubkey->serial);
 
-               if (ac != NULL && verify_x509acert(ac, strict_crl_policy))
-                       *peer_list = ac->groups;
+               if (x509ac && verify_x509acert(x509ac, strict_crl_policy))
+               {
+                       ac_t * ac = (ac_t*)x509ac->ac;
+               
+                       *peer_attributes = ac->get_groups(ac);
+               }
                else
                {
                        DBG(DBG_CONTROL,
@@ -3746,9 +3809,8 @@ connection_t *find_client_connection(connection_t *c,
 {
        connection_t *d;
        struct spd_route *sr;
-
-       const ietfAttrList_t *peer_list = NULL;
-       chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_list);
+       ietf_attributes_t *peer_attributes = NULL;
+       chunk_t peer_ca = get_peer_ca_and_groups(c, &peer_attributes);
 
 #ifdef DEBUG
        if (DBGP(DBG_CONTROLMORE))
@@ -3795,12 +3857,14 @@ connection_t *find_client_connection(connection_t *c,
                        && sr->this.port == our_port
                        && sr->that.protocol == peer_protocol
                        && sr->that.port == peer_port
-                       && group_membership(peer_list, c->name, sr->that.groups))
+                       && match_group_membership(peer_attributes, c->name, sr->that.groups))
                        {
                                passert(oriented(*c));
                                if (routed(sr->routing))
+                               {
+                                       DESTROY_IF(peer_attributes);
                                        return c;
-
+                               }
                                unrouted = c;
                        }
                }
@@ -3808,7 +3872,7 @@ connection_t *find_client_connection(connection_t *c,
                /* exact match? */
                d = fc_try(c, c->host_pair, NULL, our_net, peer_net
                        , our_protocol, our_port, peer_protocol, peer_port
-                       , peer_ca, peer_list);
+                       , peer_ca, peer_attributes);
 
                DBG(DBG_CONTROLMORE,
                        DBG_log("  fc_try %s gives %s"
@@ -3817,7 +3881,9 @@ connection_t *find_client_connection(connection_t *c,
                )
 
                if (d == NULL)
+               {
                        d = unrouted;
+               }
        }
 
        if (d == NULL)
@@ -3852,7 +3918,7 @@ connection_t *find_client_connection(connection_t *c,
                        /* RW match with actual peer_id or abstract peer_id? */
                        d = fc_try(c, hp, NULL, our_net, peer_net
                                , our_protocol, our_port, peer_protocol, peer_port
-                               , peer_ca, peer_list);
+                               , peer_ca, peer_attributes);
 
                        if (d == NULL
                        && subnetishost(our_net)
@@ -3864,7 +3930,7 @@ connection_t *find_client_connection(connection_t *c,
                                 */
                                d = fc_try_oppo(c, hp, our_net, peer_net
                                        , our_protocol, our_port, peer_protocol, peer_port
-                                       , peer_ca, peer_list);
+                                       , peer_ca, peer_attributes);
                        }
                }
        }
@@ -3873,6 +3939,7 @@ connection_t *find_client_connection(connection_t *c,
                DBG_log("  concluding with d = %s"
                                , (d ? d->name : "none"))
        )
+       DESTROY_IF(peer_attributes);
        return d;
 }
 
@@ -3978,8 +4045,7 @@ void show_connections_status(bool all, const char *name)
                                dntoa_or_null(this_ca, BUF_LEN, c->spd.this.ca, "%any");
                                dntoa_or_null(that_ca, BUF_LEN, c->spd.that.ca, "%any");
 
-                               whack_log(RC_COMMENT
-                                       , "\"%s\"%s:   CAs: '%s'...'%s'"
+                               whack_log(RC_COMMENT, "\"%s\"%s:   CAs: '%s'...'%s'"
                                        , c->name
                                        , instance
                                        , this_ca
@@ -3989,14 +4055,10 @@ void show_connections_status(bool all, const char *name)
                        /* show group attributes if defined */
                        if (c->spd.that.groups != NULL)
                        {
-                               char buf[BUF_LEN];
-
-                               format_groups(c->spd.that.groups, buf, BUF_LEN);
-                               whack_log(RC_COMMENT
-                                       , "\"%s\"%s:   groups: %s"
+                               whack_log(RC_COMMENT, "\"%s\"%s:   groups: %s"
                                        , c->name
                                        , instance
-                                       , buf);
+                                       , c->spd.that.groups->get_string(c->spd.that.groups));
                        }
 
                        whack_log(RC_COMMENT
index d688149..5bef59b 100644 (file)
@@ -146,7 +146,7 @@ struct end {
        u_int8_t protocol;
        cert_t cert;                /* end certificate */
        chunk_t ca;                 /* CA distinguished name */
-       struct ietfAttrList *groups;/* access control groups */
+       ietf_attributes_t *groups;  /* access control groups */
        smartcard_t *sc;            /* smartcard reader and key info */
        struct virtual_t *virt;
        bool modecfg;               /* this end: request local address from server */
@@ -288,8 +288,8 @@ find_connection_for_clients(struct spd_route **srp
                                                        , const ip_address *peer_client
                                                        , int transport_proto);
 
-extern chunk_t get_peer_ca_and_groups(connection_t *c
-       , const ietfAttrList_t **peer_list);
+extern chunk_t get_peer_ca_and_groups(connection_t *c,
+                                                                         ietf_attributes_t **peer_attributes);
 
 /* instantiating routines
  * Note: connection_discard() is in state.h because all its work
index 38e8027..01d4839 100644 (file)
@@ -133,7 +133,7 @@ bool insert_crl(x509crl_t *x509crl, char *crl_uri, bool cache_crl)
        lock_authcert_list("insert_crl");
 
        /* get the issuer cacert */
-       issuer_cert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
+       issuer_cert = get_authcert(issuer_dn, authKeyID, X509_CA);
        if (issuer_cert == NULL)
        {
                plog("crl issuer cacert not found");
@@ -434,7 +434,7 @@ cert_status_t verify_by_crl(const x509cert_t *cert, time_t *until,
 
                lock_authcert_list("verify_by_crl");
 
-               issuer_cert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
+               issuer_cert = get_authcert(issuer_dn, authKeyID, X509_CA);
                valid = cert_crl->issued_by(cert_crl, issuer_cert->cert);
 
                unlock_authcert_list("verify_by_crl");
index 9e94119..eaa4a7a 100644 (file)
@@ -5182,29 +5182,33 @@ stf_status quick_inR1_outI2(struct msg_digest *md)
        }
 
        /* check the peer's group attributes */
-
        {
-               const ietfAttrList_t *peer_list = NULL;
+               ietf_attributes_t *peer_attributes = NULL;
+               bool match;
 
-               get_peer_ca_and_groups(st->st_connection, &peer_list);
+               get_peer_ca_and_groups(st->st_connection, &peer_attributes);
+               match = match_group_membership(peer_attributes,
+                                                                          st->st_connection->name,
+                                                                          st->st_connection->spd.that.groups);
+               DESTROY_IF(peer_attributes);
 
-               if (!group_membership(peer_list, st->st_connection->name
-                               , st->st_connection->spd.that.groups))
+               if (!match)
                {
-                       char buf[BUF_LEN];
+                       ietf_attributes_t *groups = st->st_connection->spd.that.groups;
 
-                       format_groups(st->st_connection->spd.that.groups, buf, BUF_LEN);
-                       loglog(RC_LOG_SERIOUS, "peer is not member of one of the groups: %s"
-                               , buf);
+                       loglog(RC_LOG_SERIOUS,
+                                  "peer with attributes '%s' is not a member of the groups '%s'",
+                                       peer_attributes->get_string(peer_attributes),
+                                       groups->get_string(groups));
                        return STF_FAIL + INVALID_ID_INFORMATION;
                }
        }
 
-               if ((st->nat_traversal & NAT_T_DETECTED)
-               &&  (st->nat_traversal & NAT_T_WITH_NATOA))
-               {
-                       nat_traversal_natoa_lookup(md);
-               }
+       if ((st->nat_traversal & NAT_T_DETECTED)
+       &&  (st->nat_traversal & NAT_T_WITH_NATOA))
+       {
+               nat_traversal_natoa_lookup(md);
+       }
 
        /* ??? We used to copy the accepted proposal into the state, but it was
         * never used.  From sa_pd->pbs.start, length pbs_room(&sa_pd->pbs).
index 510667e..d980e7f 100644 (file)
@@ -329,7 +329,7 @@ static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *locatio
 
        if (authKeyID.ptr == NULL)
        {
-               x509cert_t *authcert = get_authcert(issuer_dn, authKeyID, AUTH_CA);
+               x509cert_t *authcert = get_authcert(issuer_dn, authKeyID, X509_CA);
 
                if (authcert != NULL)
                {
@@ -983,7 +983,7 @@ static bool valid_ocsp_response(response_t *res)
        lock_authcert_list("valid_ocsp_response");
 
        authcert = get_authcert(res->responder_id_name, res->responder_id_key,
-                                                       AUTH_OCSP | AUTH_CA);
+                                                       X509_OCSP_SIGNER | X509_CA);
        if (authcert == NULL)
        {
                plog("no matching ocsp signer cert found");
@@ -1040,7 +1040,7 @@ static bool valid_ocsp_response(response_t *res)
                        DBG_log("certificate is valid")
                )
 
-               authcert = get_authcert(issuer->get_encoding(issuer), authKeyID, AUTH_CA);
+               authcert = get_authcert(issuer->get_encoding(issuer), authKeyID, X509_CA);
                if (authcert == NULL)
                {
                        plog("issuer cacert not found");
@@ -1168,7 +1168,7 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
                                if ((x509->get_flags(x509) & X509_OCSP_SIGNER) &&
                                        trust_authcert_candidate(cert, NULL))
                                {
-                                       add_authcert(cert, AUTH_OCSP);
+                                       add_authcert(cert, X509_OCSP_SIGNER);
                                }
                                else
                                {
index 78afeac..203c24c 100644 (file)
@@ -720,11 +720,11 @@ int main(int argc, char **argv)
 #endif /* CAPABILITIES */
 
        /* loading X.509 CA certificates */
-       load_authcerts("CA", CA_CERT_PATH, AUTH_CA);
+       load_authcerts("CA", CA_CERT_PATH, X509_CA);
        /* loading X.509 AA certificates */
-       load_authcerts("AA", AA_CERT_PATH, AUTH_AA);
+       load_authcerts("AA", AA_CERT_PATH, X509_AA);
        /* loading X.509 OCSP certificates */
-       load_authcerts("OCSP", OCSP_CERT_PATH, AUTH_OCSP);
+       load_authcerts("OCSP", OCSP_CERT_PATH, X509_OCSP_SIGNER);
        /* loading X.509 CRLs */
        load_crls();
        /* loading attribute certificates (experimental) */
index ef984f6..d84a9f5 100644 (file)
@@ -451,17 +451,17 @@ whack_handle(int whackctlfd)
 
        if (msg.whack_reread & REREAD_CACERTS)
        {
-               load_authcerts("CA cert", CA_CERT_PATH, AUTH_CA);
+               load_authcerts("CA cert", CA_CERT_PATH, X509_CA);
        }
 
        if (msg.whack_reread & REREAD_AACERTS)
        {
-               load_authcerts("AA cert", AA_CERT_PATH, AUTH_AA);
+               load_authcerts("AA cert", AA_CERT_PATH, X509_AA);
        }
 
        if (msg.whack_reread & REREAD_OCSPCERTS)
        {
-               load_authcerts("OCSP cert", OCSP_CERT_PATH, AUTH_OCSP);
+               load_authcerts("OCSP cert", OCSP_CERT_PATH, X509_OCSP_SIGNER);
        }
 
        if (msg.whack_reread & REREAD_ACERTS)
@@ -492,17 +492,17 @@ whack_handle(int whackctlfd)
 
        if (msg.whack_list & LIST_CACERTS)
        {
-               list_authcerts("CA", AUTH_CA, msg.whack_utc);
+               list_authcerts("CA", X509_CA, msg.whack_utc);
        }
 
        if (msg.whack_list & LIST_AACERTS)
        {
-               list_authcerts("AA", AUTH_AA, msg.whack_utc);
+               list_authcerts("AA", X509_AA, msg.whack_utc);
        }
 
        if (msg.whack_list & LIST_OCSPCERTS)
        {
-               list_authcerts("OCSP", AUTH_OCSP, msg.whack_utc);
+               list_authcerts("OCSP", X509_OCSP_SIGNER, msg.whack_utc);
        }
 
        if (msg.whack_list & LIST_ACERTS)
@@ -510,11 +510,6 @@ whack_handle(int whackctlfd)
                list_acerts(msg.whack_utc);
        }
 
-       if (msg.whack_list & LIST_GROUPS)
-       {
-               list_groups(msg.whack_utc);
-       }
-
        if (msg.whack_list & LIST_CAINFOS)
        {
                list_ca_infos(msg.whack_utc);
index d0a57b3..61d2639 100644 (file)
@@ -126,8 +126,7 @@ const x509cert_t empty_x509cert = {
          NULL        , /* *next */
        UNDEFINED_TIME, /* installed */
                        0     , /* count */
-         FALSE       , /* smartcard */
-        AUTH_NONE    , /* authority_flags */
+         FALSE         /* smartcard */
 };
 
 /* coding of X.501 distinguished name */
@@ -1038,7 +1037,7 @@ void store_x509certs(x509cert_t **firstcert, bool strict)
 
                if (trust_authcert_candidate(cert, cacerts))
                {
-                       add_authcert(cert, AUTH_CA);
+                       add_authcert(cert, X509_CA);
                }
                else
                {
@@ -1393,7 +1392,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
 
                lock_authcert_list("verify_x509cert");
                issuer_cert = get_authcert(issuer->get_encoding(issuer),
-                                                                  authKeyID, AUTH_CA);
+                                                                  authKeyID, X509_CA);
                if (issuer_cert == NULL)
                {
                        plog("issuer cacert not found");
@@ -1495,7 +1494,7 @@ bool verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
  * List all X.509 certs in a chained list
  */
 void list_x509cert_chain(const char *caption, x509cert_t* cert,
-                                                u_char auth_flags, bool utc)
+                                                x509_flag_t flags, bool utc)
 {
        bool first = TRUE;
        time_t now;
@@ -1505,14 +1504,15 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
 
        while (cert != NULL)
        {
-               if (auth_flags == AUTH_NONE || (auth_flags & cert->authority_flags))
+               certificate_t *certificate = cert->cert;
+               x509_t *x509 = (x509_t*)certificate;
+
+               if (flags == X509_NONE || (flags & x509->get_flags(x509)))
                {
                        time_t notBefore, notAfter;
                        public_key_t *key;
                        chunk_t serial, keyid, subjkey, authkey;
                        cert_t c;
-                       certificate_t *certificate = cert->cert;
-                       x509_t *x509 = (x509_t*)certificate;
                        
                        c.type = CERT_X509_SIGNATURE;
                        c.u.x509 = cert;
@@ -1579,5 +1579,5 @@ void list_x509cert_chain(const char *caption, x509cert_t* cert,
  */
 void list_x509_end_certs(bool utc)
 {
-       list_x509cert_chain("End", x509certs, AUTH_NONE, utc);
+       list_x509cert_chain("End", x509certs, X509_NONE, utc);
 }
index 490ffc3..a61d6c0 100644 (file)
@@ -58,7 +58,6 @@ struct x509cert {
        time_t          installed;
        int             count;
        bool            smartcard;
-       u_char          authority_flags;
 };
 
 /* used for initialization */
@@ -91,7 +90,7 @@ extern void release_x509cert(x509cert_t *cert);
 extern void free_x509cert(x509cert_t *cert);
 extern void store_x509certs(x509cert_t **firstcert, bool strict);
 extern void list_x509cert_chain(const char *caption, x509cert_t* cert,
-                                                               u_char auth_flags, bool utc);
+                                                               x509_flag_t flags, bool utc);
 extern void list_x509_end_certs(bool utc);
 extern void free_generalNames(generalName_t* gn, bool free_name);
 
index 59f6eb7..c6c3c66 100644 (file)
@@ -1,12 +1,12 @@
 carol::ipsec status::alice.*STATE_QUICK_I2.*IPsec SA established::YES
-moon::cat /var/log/auth.log::alice.*peer matches group 'Research'::YES
+moon::cat /var/log/auth.log::alice.*peer with attributes .*Research.* is a member of the groups .*Research::YES
 moon::ipsec status::alice.*PH_IP_CAROL.*STATE_QUICK_R2.*IPsec SA established::YES
 carol::ipsec status::venus.*STATE_QUICK_I2.*IPsec SA established::NO
-moon::cat /var/log/auth.log::venus.*peer doesn't match any group::YES
+moon::cat /var/log/auth.log::venus.*peer with attributes .*Research.* is not a member of the groups .*Accounting::YES
 moon::ipsec status::venus.*PH_IP_CAROL.*STATE_QUICK_R2.*IPsec SA established::NO
 dave::ipsec status::venus.*STATE_QUICK_I2.*IPsec SA established::YES
-moon::cat /var/log/auth.log::venus.*peer matches group 'Accounting'::YES
+moon::cat /var/log/auth.log::venus.*peer with attributes .*Accounting.* is a member of the groups .*Accounting::YES
 moon::ipsec status::venus.*PH_IP_DAVE.*STATE_QUICK_R2.*IPsec SA established::YES
 dave::ipsec status::alice.*STATE_QUICK_I2.*IPsec SA established::NO
-moon::cat /var/log/auth.log::alice.*peer doesn't match any group::YES
+moon::cat /var/log/auth.log::alice.*peer with attributes .*Accounting.* is not a member of the groups .*Research::YES
 moon::ipsec status::alice.*PH_IP_DAVE.*STATE_QUICK_R2.*IPsec SA established::NO