From: Martin Willi Date: Tue, 4 Feb 2014 14:41:09 +0000 (+0100) Subject: x509: Replace fixed acert group string getter by a more dynamic group enumerator X-Git-Tag: 5.1.3rc1~24^2~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61b2d815b9af23261c479b552fb86faf212387fe;p=thirdparty%2Fstrongswan.git x509: Replace fixed acert group string getter by a more dynamic group enumerator --- diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index ea168058ff..991bed116f 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -31,8 +31,9 @@ #include #include #include -#include #include +#include +#include /* warning intervals for list functions */ #define CERT_WARNING_INTERVAL 30 /* days */ @@ -1027,16 +1028,19 @@ static void stroke_list_certs(linked_list_t *list, char *label, 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) { @@ -1061,30 +1065,78 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out) { 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"); } diff --git a/src/libstrongswan/credentials/certificates/ac.h b/src/libstrongswan/credentials/certificates/ac.h index 0bf7620172..1094cdcfd0 100644 --- a/src/libstrongswan/credentials/certificates/ac.h +++ b/src/libstrongswan/credentials/certificates/ac.h @@ -27,6 +27,16 @@ #include 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. @@ -70,11 +80,11 @@ struct ac_t { 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_ @}*/ diff --git a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c index 49af5a0799..6efbfb70e8 100644 --- a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c +++ b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c @@ -19,49 +19,26 @@ #include #include #include +#include #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); }; /** @@ -72,11 +49,11 @@ 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) + 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; } @@ -100,13 +77,11 @@ static void ietf_attr_destroy(ietf_attr_t *this) /** * 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), ); @@ -175,12 +150,12 @@ METHOD(ietf_attributes_t, get_string, char*, 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); @@ -214,6 +189,24 @@ METHOD(ietf_attributes_t, get_string, char*, 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) { @@ -243,13 +236,13 @@ METHOD(ietf_attributes_t, get_encoding, chunk_t, 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; } @@ -290,7 +283,7 @@ static bool equals(private_ietf_attributes_t *this, 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; @@ -334,8 +327,9 @@ static bool matches(private_ietf_attributes_t *this, /* 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 */ @@ -379,7 +373,7 @@ METHOD(ietf_attributes_t, destroy, void, { 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); } @@ -392,6 +386,7 @@ static private_ietf_attributes_t* create_empty(void) 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, @@ -417,13 +412,13 @@ static void ietf_attributes_add(private_ietf_attributes_t *this, 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 */ @@ -461,7 +456,7 @@ ietf_attributes_t *ietf_attributes_create_from_string(char *string) /* 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); } @@ -515,7 +510,7 @@ ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded) 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; @@ -531,4 +526,3 @@ ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded) return &(this->public); } - diff --git a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h index ab6bae9847..a34b23a3dc 100644 --- a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h +++ b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.h @@ -40,6 +40,13 @@ struct ietf_attributes_t { */ 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. * @@ -58,7 +65,7 @@ struct ietf_attributes_t { /** * 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); @@ -89,4 +96,3 @@ ietf_attributes_t *ietf_attributes_create_from_string(char *string); ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded); #endif /** IETF_ATTRIBUTES_H_ @}*/ - diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index b7da97da47..9845b21a8b 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -655,10 +655,10 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t, 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, @@ -866,7 +866,7 @@ static private_x509_ac_t *create_empty(void) .get_holderSerial = _get_holderSerial, .get_holderIssuer = _get_holderIssuer, .get_authKeyIdentifier = _get_authKeyIdentifier, - .get_groups = _get_groups, + .create_group_enumerator = _create_group_enumerator, }, }, .ref = 1,