From 65d288217ff7e5cf5370c659442a136ae33925c2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 12 Jun 2026 15:55:43 +0200 Subject: [PATCH] x509: Fix memory leaks when parsing attribute certificates This can be triggered by an attribute certificate with lots of GeneralName entries or AuthorityKeyIdentifier extensions. There is no verification before the certificate is parsed. Fixes: 3134379ac7f1 ("x509: Fix some whitespaces and do some minor style cleanups in acert") Fixes: 26930a8c3e42 ("certificate factory can load certs from file") Fixes: CVE-2026-78131 --- src/libstrongswan/plugins/x509/x509_ac.c | 30 +++++++----------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index aea8eb53db4b..e999b9004652 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -185,37 +185,22 @@ extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name) { - identification_t *directoryName; - enumerator_t *enumerator; - bool first = TRUE; linked_list_t *list; list = linked_list_create(); x509_parse_generalNames(blob, level, implicit, list); - enumerator = list->create_enumerator(list); - while (enumerator->enumerate(enumerator, &directoryName)) - { - if (first) - { - *name = directoryName; - first = FALSE; - } - else - { - DBG1(DBG_ASN, "more than one directory name - first selected"); - directoryName->destroy(directoryName); - break; - } - } - enumerator->destroy(enumerator); - list->destroy(list); - - if (first) + if (list->remove_first(list, (void**)name) != SUCCESS) { DBG1(DBG_ASN, "no directoryName found"); + list->destroy(list); return FALSE; } + if (list->get_count(list)) + { + DBG1(DBG_ASN, "more than one directory name - first selected"); + } + list->destroy_offset(list, offsetof(identification_t, destroy)); return TRUE; } @@ -531,6 +516,7 @@ static bool parse_certificate(private_x509_ac_t *this) DBG2(DBG_ASN, " need to parse crlDistributionPoints"); break; case OID_AUTHORITY_KEY_ID: + chunk_free(&this->authKeyIdentifier); this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object, level, &this->authKeySerialNumber); -- 2.43.0