]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
credential-factory: Enforce an upper limit when creating nested credentials
authorTobias Brunner <tobias@strongswan.org>
Fri, 20 Mar 2026 16:20:55 +0000 (17:20 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 2 Apr 2026 06:16:07 +0000 (08:16 +0200)
This mainly intended as defense-in-depth measure to avoid parsing
massively nested structures that could cause a call stack overflow due
to the massive recursion.  In particular PKCS#7 signed data is prone to
this as these can be nested basically infinitely.  When used in IKEv1 via
ENC_PKCS7_WRAPPED_X509 CERT payloads, our default of 10000 bytes for IKE
messages guards against this, but that's configurable and there might be
a chance for some bug that triggers problematic recursive parsing for
smaller input.

The upper limit is chosen arbitrarily, but there are currently no known
cases that require a depth of more than 10 levels.

src/libstrongswan/credentials/credential_factory.c

index 07e1de76e80a746351fc4446c38874568d4dd121..15f4ba9a456cc1283a4ef9072cf935950fda0234 100644 (file)
 #include <credentials/certificates/x509.h>
 #include <credentials/containers/container.h>
 
+/**
+ * Maximum depth/recursion before failing to create a credential.
+ */
+#define CREATE_MAX_DEPTH 10
+
 ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CONTAINER,
        "CRED_PRIVATE_KEY",
        "CRED_PUBLIC_KEY",
@@ -137,6 +142,12 @@ METHOD(credential_factory_t, create, void*,
        }
 
        level = (uintptr_t)this->recursive->get(this->recursive);
+       if (level >= CREATE_MAX_DEPTH)
+       {
+               DBG1(DBG_LIB, "building %N - %N failed, reached depth limit (%d)",
+                        credential_type_names, type, names, subtype, CREATE_MAX_DEPTH);
+               return NULL;
+       }
        this->recursive->set(this->recursive, (void*)level + 1);
 
        this->lock->read_lock(this->lock);