From d925e4625626a70611a979d4ab231c6e2d313e4a Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 1 Jul 2026 16:24:23 +0200 Subject: [PATCH] x509: Prevent infinite loop when parsing ietfAttrSyntax in attribute certificates This is the same issue that was fixed with 407fcca200fd ("asn1-parser: Fix CHOICE parsing") for other CHOICE elements. This one was missed and can be triggered pre-auth by sending an attribute certificate to a peer. Since it's parsed before verifying it, the certificate doesn't have to be valid. For versions older than 5.5.3, this patch requires prior application of the fix for CVE-2017-9023, which introduced proper CHOICE handling in the ASN.1 parser. Fixes: a17598bc6992 ("x509: Integrate IETF attribute handling, and obsolete ietf_attributes_t") Fixes: CVE-2026-78132 --- src/libstrongswan/plugins/x509/x509_ac.c | 36 +++++++++++------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index 4436bc4debef..e8e34749a59c 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -249,26 +249,24 @@ static void parse_roleSyntax(chunk_t blob, int level0) */ 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 } + { 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, "value choice", ASN1_EOC, ASN1_CHOICE }, /* 4 */ + { 3, "octets", ASN1_OCTET_STRING, ASN1_OPT|ASN1_BODY }, /* 5 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 6 */ + { 3, "oid", ASN1_OID, ASN1_OPT|ASN1_BODY }, /* 7 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 8 */ + { 3, "string", ASN1_UTF8STRING, ASN1_OPT|ASN1_BODY }, /* 9 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 10 */ + { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 11 */ + { 1, "end loop", ASN1_EOC, ASN1_END }, /* 12 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; -#define IETF_ATTR_OCTETS 4 -#define IETF_ATTR_OID 6 -#define IETF_ATTR_STRING 8 +#define IETF_ATTR_OCTETS 5 +#define IETF_ATTR_OID 7 +#define IETF_ATTR_STRING 9 /** * Parse group memberships, IETF attributes -- 2.43.0