#include <credentials/certificates/ac.h>
#include <credentials/certificates/crl.h>
#include <credentials/certificates/pgp_certificate.h>
-#include <credentials/ietf_attributes/ietf_attributes.h>
#include <config/peer_cfg.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
/* warning intervals for list functions */
#define CERT_WARNING_INTERVAL 30 /* days */
static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
{
bool first = TRUE;
- time_t thisUpdate, nextUpdate, now = time(NULL);
- enumerator_t *enumerator = list->create_enumerator(list);
+ time_t notBefore, notAfter, now = time(NULL);
+ enumerator_t *enumerator;
certificate_t *cert;
- while (enumerator->enumerate(enumerator, (void**)&cert))
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &cert))
{
ac_t *ac = (ac_t*)cert;
+ ac_group_type_t type;
identification_t *id;
- ietf_attributes_t *groups;
+ enumerator_t *groups;
chunk_t chunk;
+ bool firstgroup = TRUE;
if (first)
{
{
fprintf(out, " hserial: %#B\n", &chunk);
}
- groups = ac->get_groups(ac);
- if (groups)
+ groups = ac->create_group_enumerator(ac);
+ while (groups->enumerate(groups, &type, &chunk))
{
- fprintf(out, " groups: %s\n", groups->get_string(groups));
- groups->destroy(groups);
+ int oid;
+ char *str;
+
+ if (firstgroup)
+ {
+ fprintf(out, " groups: ");
+ firstgroup = FALSE;
+ }
+ else
+ {
+ fprintf(out, " ");
+ }
+ switch (type)
+ {
+ case AC_GROUP_TYPE_STRING:
+ fprintf(out, "%.*s", (int)chunk.len, chunk.ptr);
+ break;
+ case AC_GROUP_TYPE_OID:
+ oid = asn1_known_oid(chunk);
+ if (oid == OID_UNKNOWN)
+ {
+ str = asn1_oid_to_string(chunk);
+ if (str)
+ {
+ fprintf(out, "%s", str);
+ }
+ else
+ {
+ fprintf(out, "OID:%#B", &chunk);
+ }
+ }
+ else
+ {
+ fprintf(out, "%s", oid_names[oid].name);
+ }
+ break;
+ case AC_GROUP_TYPE_OCTETS:
+ fprintf(out, "%#B", &chunk);
+ break;
+ }
+ fprintf(out, "\n");
}
+ groups->destroy(groups);
fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
chunk = chunk_skip_zero(ac->get_serial(ac));
fprintf(out, " serial: %#B\n", &chunk);
/* list validity */
- cert->get_validity(cert, &now, &thisUpdate, &nextUpdate);
- fprintf(out, " updates: this %T\n", &thisUpdate, utc);
- fprintf(out, " next %T, ", &nextUpdate, utc);
- if (now > nextUpdate)
+ cert->get_validity(cert, &now, ¬Before, ¬After);
+ fprintf(out, " validity: not before %T, ", ¬Before, utc);
+ if (now < notBefore)
{
- fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
+ fprintf(out, "not valid yet (valid in %V)\n", &now, ¬Before);
+ }
+ else
+ {
+ fprintf(out, "ok\n");
+ }
+ fprintf(out, " not after %T, ", ¬After, utc);
+ if (now > notAfter)
+ {
+ fprintf(out, "expired (%V ago)\n", &now, ¬After);
}
else
{
fprintf(out, "ok");
- if (now > nextUpdate - AC_WARNING_INTERVAL * 60 * 60 * 24)
+ if (now > notAfter - AC_WARNING_INTERVAL * 60 * 60 * 24)
{
- fprintf(out, " (expires in %V)", &now, &nextUpdate);
+ fprintf(out, " (expires in %V)", &now, ¬After);
}
fprintf(out, " \n");
}
#include <credentials/ietf_attributes/ietf_attributes.h>
typedef struct ac_t ac_t;
+typedef enum ac_group_type_t ac_group_type_t;
+
+/**
+ * Common group types, from IETF Attributes Syntax
+ */
+enum ac_group_type_t {
+ AC_GROUP_TYPE_OCTETS,
+ AC_GROUP_TYPE_STRING,
+ AC_GROUP_TYPE_OID,
+};
/**
* X.509 attribute certificate interface.
chunk_t (*get_authKeyIdentifier)(ac_t *this);
/**
- * Get the group memberships as a list of IETF attributes
+ * Create an enumerator of contained Group memberships.
*
- * @return object containing a list of IETF attributes
+ * @return enumerator over (ac_group_type_t, chunk_t)
*/
- ietf_attributes_t* (*get_groups)(ac_t *this);
+ enumerator_t* (*create_group_enumerator)(ac_t *this);
};
#endif /** AC_H_ @}*/
#include <asn1/asn1_parser.h>
#include <collections/linked_list.h>
#include <utils/lexparser.h>
+#include <credentials/certificates/ac.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;
+ ac_group_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);
};
/**
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)
+ if (this->type != AC_GROUP_TYPE_OID && other->type == AC_GROUP_TYPE_OID)
{
return -1;
}
- if (this->type == IETF_ATTRIBUTE_OID && other->type != IETF_ATTRIBUTE_OID)
+ if (this->type == AC_GROUP_TYPE_OID && other->type != AC_GROUP_TYPE_OID)
{
return 1;
}
/**
* Creates an ietf_attr_t object.
*/
-static ietf_attr_t* ietf_attr_create(ietf_attribute_type_t type, chunk_t value)
+static ietf_attr_t* ietf_attr_create(ac_group_type_t type, chunk_t value)
{
ietf_attr_t *this;
INIT(this,
- .compare = ietf_attr_compare,
- .destroy = ietf_attr_destroy,
.type = type,
.value = chunk_clone(value),
);
switch (attr->type)
{
- case IETF_ATTRIBUTE_OCTETS:
- case IETF_ATTRIBUTE_STRING:
+ case AC_GROUP_TYPE_OCTETS:
+ case AC_GROUP_TYPE_STRING:
written = snprintf(pos, len, "%.*s", (int)attr->value.len,
attr->value.ptr);
break;
- case IETF_ATTRIBUTE_OID:
+ case AC_GROUP_TYPE_OID:
{
int oid = asn1_known_oid(attr->value);
return this->string;
}
+/**
+ * Filter function for attribute enumeration
+ */
+static bool attr_filter(void *null, ietf_attr_t **in, ac_group_type_t *type,
+ void *in2, chunk_t *out)
+{
+ *type = (*in)->type;
+ *out = (*in)->value;
+ return TRUE;
+}
+
+METHOD(ietf_attributes_t, create_enumerator, enumerator_t*,
+ private_ietf_attributes_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)attr_filter, NULL, NULL);
+}
+
METHOD(ietf_attributes_t, get_encoding, chunk_t,
private_ietf_attributes_t *this)
{
switch (attr->type)
{
- case IETF_ATTRIBUTE_OCTETS:
+ case AC_GROUP_TYPE_OCTETS:
type = ASN1_OCTET_STRING;
break;
- case IETF_ATTRIBUTE_STRING:
+ case AC_GROUP_TYPE_STRING:
type = ASN1_UTF8STRING;
break;
- case IETF_ATTRIBUTE_OID:
+ case AC_GROUP_TYPE_OID:
type = ASN1_OID;
break;
}
while (enum_a->enumerate(enum_a, &attr_a) &&
enum_b->enumerate(enum_b, &attr_b))
{
- if (attr_a->compare(attr_a, attr_b) != 0)
+ if (ietf_attr_compare(attr_a, attr_b) != 0)
{
/* we have a mismatch */
result = FALSE;
/* look for at least one common attribute */
while (TRUE)
{
- int cmp = attr_a->compare(attr_a, attr_b);
+ int cmp;
+ cmp = ietf_attr_compare(attr_a, attr_b);
if (cmp == 0)
{
/* we have a match */
{
if (ref_put(&this->ref))
{
- this->list->destroy_offset(this->list, offsetof(ietf_attr_t, destroy));
+ this->list->destroy_function(this->list, (void*)ietf_attr_destroy);
free(this->string);
free(this);
}
INIT(this,
.public = {
.get_string = _get_string,
+ .create_enumerator = _create_enumerator,
.get_encoding = _get_encoding,
.equals = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))equals,
.matches = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))matches,
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, (void **)¤t_attr) &&
- (cmp = attr->compare(attr, current_attr)) > 0)
+ (cmp = ietf_attr_compare(attr, current_attr)) > 0)
{
continue;
}
if (cmp == 0)
{
- attr->destroy(attr);
+ ietf_attr_destroy(attr);
}
else
{ /* the enumerator either points to the end or to the attribute > attr */
/* add the group attribute to the list */
if (group.len > 0)
{
- ietf_attr_t *attr = ietf_attr_create(IETF_ATTRIBUTE_STRING, group);
+ ietf_attr_t *attr = ietf_attr_create(AC_GROUP_TYPE_STRING, group);
ietf_attributes_add(this, attr);
}
case IETF_ATTR_OID:
case IETF_ATTR_STRING:
{
- ietf_attribute_type_t type;
+ ac_group_type_t type;
ietf_attr_t *attr;
type = (objectID - IETF_ATTR_OCTETS) / 2;
return &(this->public);
}
-
*/
char* (*get_string) (ietf_attributes_t *this);
+ /**
+ * Create an enumerator over attributes.
+ *
+ * @return enumerator over (ac_group_type_t, chunk_t)
+ */
+ enumerator_t* (*create_enumerator)(ietf_attributes_t *this);
+
/**
* Get the ASN.1 encoding of the IETF attributes.
*
/**
* Check for common attributes between two lists.
*
- * @param other attribute list to be matched
+ * @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);
ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded);
#endif /** IETF_ATTRIBUTES_H_ @}*/
-
return this->authKeyIdentifier;
}
-METHOD(ac_t, get_groups, ietf_attributes_t*,
+METHOD(ac_t, create_group_enumerator, enumerator_t*,
private_x509_ac_t *this)
{
- return this->groups ? this->groups->get_ref(this->groups) : NULL;
+ return this->groups->create_enumerator(this->groups);
}
METHOD(certificate_t, get_type, certificate_type_t,
.get_holderSerial = _get_holderSerial,
.get_holderIssuer = _get_holderIssuer,
.get_authKeyIdentifier = _get_authKeyIdentifier,
- .get_groups = _get_groups,
+ .create_group_enumerator = _create_group_enumerator,
},
},
.ref = 1,