Ankur Tyagi authored and Anuj Mittal committed 2026-10-06 09:50:48 +05:30
1 parent 7b8fd4df2e
commit 9ea8363e30
2 files changed
+156

No files matched your search

@@ -0,0 +1,155 @@
From ec14a504137915cc45080323238c64d348d020eb Mon Sep 17 00:00:00 2001
From: Tobias Brunner <tobias@strongswan.org>
Date: Tue, 23 Jun 2026 11:55:31 +0200
Subject: [PATCH] pkcs5: Validate parsed parameters to avoid DoS attacks
With the unbounded iterations, an attacker can craft a PKCS#7 file and
send it during IKEv1 to block the processing thread practically for an
unlimited amount of time.
As the key length is used for an allocation on the stack, not limiting
it could cause a crash. We validate it after parsing the params, but
since `encryption_algorithm_from_oid()` only returns trusted key lengths
that are lower than the limit, that's fine.
The unlimited salt length had no direct impact (the maximum is bound by
the accepted message size), but we now limit it as well before cloning.
Fixes: 4076e3ee9121 ("Extract PKCS#5 handling from pkcs8 plugin to separate helper class")
Fixes: fd1ff46f6143 ("Added support for PKCS#5 v2 schemes when decrypting PKCS#8 files.")
Fixes: cab127cba66c ("Added support for encrypted PKCS#8 files (for some PKCS#5 v1.5 schemes).")
Fixes: CVE-2026-78129
CVE: CVE-2026-78129
Upstream-Status: Backport [https://github.com/strongswan/strongswan/commit/f60a55e36f95e210ab067de295c9f6bacefcdd1a]
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
src/libstrongswan/crypto/pkcs5.c | 65 +++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)
diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c
index 822656f..e01010b 100644
--- a/src/libstrongswan/crypto/pkcs5.c
+++ b/src/libstrongswan/crypto/pkcs5.c
@@ -14,6 +14,8 @@
* for more details.
*/
+#include <inttypes.h>
+
#include "pkcs5.h"
#include <utils/debug.h>
@@ -22,6 +24,15 @@
#include <asn1/asn1_parser.h>
#include <credentials/containers/pkcs12.h>
+/** maximum accepted length for salts in parsed parameters */
+#define PKCS5_SALT_LEN_MAX 128
+
+/** maximum accepted iteration count in parsed parameters */
+#define PKCS5_ITERATIONS_MAX 1000000
+
+/** maximum key length accepted in parsed parameters */
+#define PKCS5_KEY_LEN_MAX 64
+
typedef struct private_pkcs5_t private_pkcs5_t;
/**
@@ -379,6 +390,41 @@ METHOD(pkcs5_t, decrypt, bool,
keymat, key, iv);
}
+/**
+ * Make sure the salt has an appropriate length
+ */
+static bool validate_salt_length(chunk_t salt)
+{
+ if (salt.len > PKCS5_SALT_LEN_MAX)
+ {
+ DBG1(DBG_ASN, " salt length %zu exceeds maximum of %zu bytes",
+ salt.len, (size_t)PKCS5_SALT_LEN_MAX);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Validate that parsed parameters are in an allowed range
+ */
+static bool validate_params(private_pkcs5_t *this)
+{
+ if (!this->iterations || this->iterations > PKCS5_ITERATIONS_MAX)
+ {
+ DBG1(DBG_ASN, " iteration count %" PRIu64 " is out of range "
+ "(1-%" PRIu64 ")", this->iterations,
+ (uint64_t)PKCS5_ITERATIONS_MAX);
+ return FALSE;
+ }
+ if (this->keylen > PKCS5_KEY_LEN_MAX)
+ {
+ DBG1(DBG_ASN, " key length %zu exceeds maximum of %zu bytes",
+ this->keylen, (size_t)PKCS5_KEY_LEN_MAX);
+ return FALSE;
+ }
+ return TRUE;
+}
+
/**
* ASN.1 definition of a PBEParameter structure
*/
@@ -399,7 +445,7 @@ static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
asn1_parser_t *parser;
chunk_t object;
int objectID;
- bool success;
+ bool success = FALSE;
parser = asn1_parser_create(pbeParameterObjects, blob);
parser->set_top_level(parser, level0);
@@ -410,6 +456,10 @@ static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
{
case PBEPARAM_SALT:
{
+ if (!validate_salt_length(object))
+ {
+ goto end;
+ }
this->salt = chunk_clone(object);
break;
}
@@ -421,6 +471,11 @@ static bool parse_pbes1_params(private_pkcs5_t *this, chunk_t blob, int level0)
}
}
success = parser->success(parser);
+ if (success)
+ {
+ success = validate_params(this);
+ }
+end:
parser->destroy(parser);
return success;
}
@@ -471,6 +526,10 @@ static bool parse_pbkdf2_params(private_pkcs5_t *this, chunk_t blob, int level0)
{
case PBKDF2_SALT:
{
+ if (!validate_salt_length(object))
+ {
+ goto end;
+ }
this->salt = chunk_clone(object);
break;
}
@@ -500,6 +559,10 @@ static bool parse_pbkdf2_params(private_pkcs5_t *this, chunk_t blob, int level0)
}
}
success = parser->success(parser);
+ if (success)
+ {
+ success = validate_params(this);
+ }
end:
parser->destroy(parser);
return success;
@@ -14,6 +14,7 @@ SRC_URI = "https://download.strongswan.org/strongswan-${PV}.tar.bz2 \
file://CVE-2026-78124.patch \
file://CVE-2026-78126.patch \
file://CVE-2026-78127.patch \
file://CVE-2026-78129.patch \
"
SRC_URI[sha256sum] = "07df7cedae56a7f3bb07e66d21a1f9f87e961db70e99184e11d3819413e4f87c"