From 7012f6263df493b62268954675b0311248780309 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 | 33 +++++++----------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index 3fc5de2f1186..68b7cf927dbf 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -186,41 +186,25 @@ extern bool 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(); if (!x509_parse_generalNames(blob, level, implicit, list)) { - list->destroy(list); + list->destroy_offset(list, offsetof(identification_t, destroy)); return FALSE; } - - 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; } @@ -539,6 +523,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