From: Tobias Brunner Date: Fri, 9 Oct 2020 15:42:08 +0000 (+0200) Subject: pkcs7: Order DER encoded attributes X-Git-Tag: 5.9.1rc1~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5baa4cbd69c20d00505c7f511ace0b4ab063f60;p=thirdparty%2Fstrongswan.git pkcs7: Order DER encoded attributes The attributes are encoded as a SET OF, which means that in DER encoding the encoded attributes have to be ordered lexicographically. Fixes #3589. --- diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_attributes.c b/src/libstrongswan/plugins/pkcs7/pkcs7_attributes.c index 445dedcf79..0ec6b0c35b 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_attributes.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_attributes.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "pkcs7_attributes.h" @@ -92,6 +93,14 @@ static attribute_t *attribute_create(int oid, chunk_t value) return this; } +/** + * Compare two encoded attributes + */ +static int cmp_attributes(const chunk_t *a, const chunk_t *b, void *unused) +{ + return chunk_compare(*a, *b); +} + /** * Build encoding of the attribute list */ @@ -100,31 +109,35 @@ static void build_encoding(private_pkcs7_attributes_t *this) enumerator_t *enumerator; attribute_t *attribute; u_int len = 0, count, i = 0; - chunk_t *chunks; + array_t *chunks; + chunk_t chunk; u_char *pos; count = this->attributes->get_count(this->attributes); - chunks = malloc(sizeof(chunk_t) * count); + chunks = array_create(sizeof(chunk_t), count); enumerator = this->attributes->create_enumerator(this->attributes); while (enumerator->enumerate(enumerator, &attribute)) { - chunks[i] = asn1_wrap(ASN1_SEQUENCE, "mm", - asn1_build_known_oid(attribute->oid), - asn1_wrap(ASN1_SET, "c", attribute->value)); - len += chunks[i].len; - i++; + chunk = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(attribute->oid), + asn1_wrap(ASN1_SET, "c", attribute->value)); + array_insert(chunks, ARRAY_TAIL, &chunk); + len += chunk.len; } enumerator->destroy(enumerator); + array_sort(chunks, (void*)cmp_attributes, NULL); + pos = asn1_build_object(&this->encoding, ASN1_SET, len); for (i = 0; i < count; i++) { - memcpy(pos, chunks[i].ptr, chunks[i].len); - pos += chunks[i].len; - free(chunks[i].ptr); + array_get(chunks, i, &chunk); + memcpy(pos, chunk.ptr, chunk.len); + pos += chunk.len; + free(chunk.ptr); } - free(chunks); + array_destroy(chunks); } METHOD(pkcs7_attributes_t, get_encoding, chunk_t,