Version in base suite: 5.9.8-5+deb12u2 Version in overlay suite: 5.9.8-5+deb12u3 Base version: strongswan_5.9.8-5+deb12u3 Target version: strongswan_5.9.8-5+deb12u4 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/strongswan/strongswan_5.9.8-5+deb12u3.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/strongswan/strongswan_5.9.8-5+deb12u4.dsc changelog | 19 patches/0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch | 53 ++ patches/0010-libradius-Reject-undersized-attributes-in-enumerator.patch | 40 + patches/0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch | 49 + patches/0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch | 41 + patches/0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch | 56 ++ patches/0014-constraints-Case-insensitive-matching-and-reject-exc.patch | 123 +++++ patches/0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch | 246 ++++++++++ patches/series | 7 po/cs.po | 2 po/da.po | 2 po/de.po | 2 po/es.po | 2 po/eu.po | 2 po/fi.po | 2 po/fr.po | 2 po/gl.po | 2 po/it.po | 2 po/ja.po | 2 po/nb.po | 2 po/nl.po | 2 po/pl.po | 2 po/pt.po | 2 po/pt_BR.po | 2 po/ru.po | 2 po/sv.po | 2 po/templates.pot | 2 po/tr.po | 2 po/vi.po | 2 29 files changed, 654 insertions(+), 20 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpy_uv1wd7/strongswan_5.9.8-5+deb12u3.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpy_uv1wd7/strongswan_5.9.8-5+deb12u4.dsc: no acceptable signature found diff -Nru strongswan-5.9.8/debian/changelog strongswan-5.9.8/debian/changelog --- strongswan-5.9.8/debian/changelog 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/changelog 2026-04-13 09:19:15.000000000 +0000 @@ -1,3 +1,22 @@ +strongswan (5.9.8-5+deb12u4) bookworm-security; urgency=medium + + * d/patches: add fix for integer underflow in libsimaka when handling + EAP-SIM/AKA attributes (CVE-2026-35330) + * d/patches: add fix for integer underflow in libradius when handling RADIUS + attributes (CVE-2026-35333) + * d/patches: add fix for NULL-pointer dereference in libtls when handling + ECDH public values (CVE-2026-35332) + * d/patches: add fix for infinite loop in libtls when handling supported + versions TLS extension (CVE-2026-35328) + * d/patches: add fix for NULL-pointer dereference in libstrongswan (pkcs5) + and the pkcs7 plugin when processing padding in PKCS#7 (CVE-2026-35329) + * d/patches: add fix for acceptation of authentication certificates + violating name constraints (CVE-2026-35331) + * d/patches: add fix for possible NULL-pointer dereference in gmp plugin for + RSA decryption (CVE-2026-35334) + + -- Yves-Alexis Perez Mon, 13 Apr 2026 11:19:15 +0200 + strongswan (5.9.8-5+deb12u3) bookworm-security; urgency=medium * d/patch: fix integer overflow in EAP-TTLS plugin (CVE-2026-25075) diff -Nru strongswan-5.9.8/debian/patches/0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch strongswan-5.9.8/debian/patches/0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch --- strongswan-5.9.8/debian/patches/0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,53 @@ +From: =?utf-8?q?Lukas_Johannes_M=C3=B6ller?= +Date: Wed, 11 Mar 2026 16:07:10 +0000 +Subject: libsimaka: Reject zero-length EAP-SIM/AKA attributes +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +parse_attributes() accepts hdr->length == 0 in the AT_ENCR_DATA, +AT_RAND, AT_PADDING, default branches. The code then subtracts the +fixed attribute header size from the encoded length, which underflows +and exposes a wrapped payload length to later code. In particular, +for the cases where add_attribute() is called, this causes a heap-based +buffer overflow (a buffer of 12 bytes is allocated to which the wrapped +length is written). For AT_PADDING, the underflow is irrelevant as +add_attribute() is not called. Instead, this results in an infinite loop. + +Reject zero-length attributes before subtracting the attribute header. + +Signed-off-by: Lukas Johannes Möller + +Fixes: f8330d03953b ("Added a libsimaka library with shared message handling code for EAP-SIM/AKA") +Fixes: CVE-2026-35330 +--- + src/libsimaka/simaka_message.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/libsimaka/simaka_message.c b/src/libsimaka/simaka_message.c +index 6706568..4862048 100644 +--- a/src/libsimaka/simaka_message.c ++++ b/src/libsimaka/simaka_message.c +@@ -416,7 +416,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in) + case AT_ENCR_DATA: + case AT_RAND: + { +- if (hdr->length * 4 > in.len || in.len < 4) ++ if (hdr->length == 0 || hdr->length * 4 > in.len || in.len < 4) + { + return invalid_length(hdr->type); + } +@@ -439,7 +439,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in) + case AT_PADDING: + default: + { +- if (hdr->length * 4 > in.len || in.len < 4) ++ if (hdr->length == 0 || hdr->length * 4 > in.len || in.len < 4) + { + return invalid_length(hdr->type); + } +@@ -932,4 +932,3 @@ simaka_message_t *simaka_message_create(bool request, uint8_t identifier, + return simaka_message_create_data(chunk_create((char*)&hdr, sizeof(hdr)), + crypto); + } +- diff -Nru strongswan-5.9.8/debian/patches/0010-libradius-Reject-undersized-attributes-in-enumerator.patch strongswan-5.9.8/debian/patches/0010-libradius-Reject-undersized-attributes-in-enumerator.patch --- strongswan-5.9.8/debian/patches/0010-libradius-Reject-undersized-attributes-in-enumerator.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0010-libradius-Reject-undersized-attributes-in-enumerator.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,40 @@ +From: =?utf-8?q?Lukas_Johannes_M=C3=B6ller?= +Date: Thu, 12 Mar 2026 10:24:45 +0000 +Subject: libradius: Reject undersized attributes in enumerator +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +attribute_enumerate() accepts RADIUS attributes whose length byte is +smaller than sizeof(rattr_t) (2). For length == 0, the iterator never +advances and traps callers — including verify() — in a non-advancing +loop. For length == 1, misaligned packed-struct reads occur. + +Add a separate check for this->next->length < sizeof(rattr_t) after +the existing truncation guard. This mirrors radius_message_parse(), +which already distinguishes invalid length from truncation. + +Signed-off-by: Lukas Johannes Möller + +Fixes: 4a6b84a93461 ("reintegrated eap-radius branch into trunk") +Fixes: CVE-2026-35333 +--- + src/libradius/radius_message.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/libradius/radius_message.c b/src/libradius/radius_message.c +index 8e2db0c..5679e47 100644 +--- a/src/libradius/radius_message.c ++++ b/src/libradius/radius_message.c +@@ -261,6 +261,11 @@ METHOD(enumerator_t, attribute_enumerate, bool, + DBG1(DBG_IKE, "RADIUS message truncated"); + return FALSE; + } ++ if (this->next->length < sizeof(rattr_t)) ++ { ++ DBG1(DBG_IKE, "RADIUS attribute has invalid length"); ++ return FALSE; ++ } + *type = this->next->type; + data->ptr = this->next->value; + data->len = this->next->length - sizeof(rattr_t); diff -Nru strongswan-5.9.8/debian/patches/0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch strongswan-5.9.8/debian/patches/0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch --- strongswan-5.9.8/debian/patches/0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,49 @@ +From: Tobias Brunner +Date: Fri, 20 Mar 2026 17:38:07 +0100 +Subject: tls-server: Only accept non-empty ECDH public keys with TLS < 1.3 + +This prevents a crash due to a null-pointer dereference when processing +an empty ECDH public key. + +The previous length check only applied in the `!ec` case, so in the `ec` +case, the access to `pub.ptr[0]` was unguarded. If a crafted TLS +record ends with an empty ClientKeyExchange, then `read_data8` sets +`pub` to `chunk_empty`, causing a null-pointer dereference. + +Note that if some data follows the empty ClientKeyExchange, this just +causes a 1-byte out-of-bounds read that has no further effect as the +TLS session is aborted immediately. Either because the read value +doesn't equal TLS_ANSI_UNCOMPRESSED or because the empty public key +is rejected by `set_public_key()`. + +The referenced commit that introduced the pointer access, added the +check for `pub.len` specifically to the `!ec` case, while the pointer +access was initially unconditional (probably because the code was just +copied from `tls_peer.c` which processes ECDH public keys in a separate +function, so there was no `ec` flag). The latter was fixed a couple of +days later with 7b3c01845f63 ("Read the compression type byte for EC +groups, only"). However, that commit didn't change the length check. +Anyway, it's possible that the original intention was to add the check +to the `ec` case on the previous line, or that there was some confusion +with the parenthesis and something like the current code was intended to +begin with. + +Fixes: e6cce7ff0d1b ("Prepend point format to ECDH public key") +Fixes: CVE-2026-35332 +--- + src/libtls/tls_server.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c +index 573893f..7321bd1 100644 +--- a/src/libtls/tls_server.c ++++ b/src/libtls/tls_server.c +@@ -860,7 +860,7 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this, + group = this->dh->get_method(this->dh); + ec = key_exchange_is_ecdh(group); + if ((ec && !reader->read_data8(reader, &pub)) || +- (!ec && (!reader->read_data16(reader, &pub) || pub.len == 0))) ++ (!ec && !reader->read_data16(reader, &pub)) || pub.len == 0) + { + DBG1(DBG_TLS, "received invalid Client Key Exchange"); + this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); diff -Nru strongswan-5.9.8/debian/patches/0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch strongswan-5.9.8/debian/patches/0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch --- strongswan-5.9.8/debian/patches/0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,41 @@ +From: Tobias Brunner +Date: Wed, 25 Mar 2026 10:17:46 +0100 +Subject: tls-server: Prevent infinite loop if supported versions are too + short + +If the extension doesn't contain a multiple of two bytes, the previous +code would get stuck in an infinite loop as `remaining()` continued to +return TRUE while `read_uint16()` failed to parse a value. Initiating +several connections with such an extension allows a DoS attack as no +threads would eventually be available to handle packets/events. + +Fixes: 7fbe2e27ecf6 ("tls-server: TLS 1.3 support for TLS server implementation") +Fixes: CVE-2026-35328 +--- + src/libtls/tls_server.c | 11 ++++------- + 1 file changed, 4 insertions(+), 7 deletions(-) + +diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c +index 7321bd1..b4e6b78 100644 +--- a/src/libtls/tls_server.c ++++ b/src/libtls/tls_server.c +@@ -471,15 +471,12 @@ static status_t process_client_hello(private_tls_server_t *this, + bio_reader_t *client_versions; + + client_versions = bio_reader_create(versions); +- while (client_versions->remaining(client_versions)) ++ while (client_versions->read_uint16(client_versions, &version)) + { +- if (client_versions->read_uint16(client_versions, &version)) ++ if (this->tls->set_version(this->tls, version, version)) + { +- if (this->tls->set_version(this->tls, version, version)) +- { +- this->client_version = version; +- break; +- } ++ this->client_version = version; ++ break; + } + } + client_versions->destroy(client_versions); diff -Nru strongswan-5.9.8/debian/patches/0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch strongswan-5.9.8/debian/patches/0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch --- strongswan-5.9.8/debian/patches/0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,56 @@ +From: Tobias Brunner +Date: Wed, 25 Mar 2026 10:28:45 +0100 +Subject: pkcs5/pkcs7: Avoid NULL pointer dereference when verifying padding + +Can be triggered via empty PKCS#7 encrypted- or enveloped-data content +in IKEv1 CERT payload. + +Fixes: 4076e3ee9121 ("Extract PKCS#5 handling from pkcs8 plugin to separate helper class") +Fixes: d7aa09104f08 ("Implement PKCS#7 enveloped-data parsing and decryption") +Fixes: CVE-2026-35329 +--- + src/libstrongswan/crypto/pkcs5.c | 5 +++++ + src/libstrongswan/plugins/pkcs7/pkcs7_enveloped_data.c | 14 +++++++++++--- + 2 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c +index e48a9ad..4851d3f 100644 +--- a/src/libstrongswan/crypto/pkcs5.c ++++ b/src/libstrongswan/crypto/pkcs5.c +@@ -113,6 +113,11 @@ static bool verify_padding(crypter_t *crypter, chunk_t *blob) + { + uint8_t padding, count; + ++ if (!blob->len) ++ { ++ return FALSE; ++ } ++ + padding = count = blob->ptr[blob->len - 1]; + + if (padding > crypter->get_block_size(crypter)) +diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_enveloped_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_enveloped_data.c +index 14bfaf3..e78af19 100644 +--- a/src/libstrongswan/plugins/pkcs7/pkcs7_enveloped_data.c ++++ b/src/libstrongswan/plugins/pkcs7/pkcs7_enveloped_data.c +@@ -182,9 +182,17 @@ static bool decrypt(private_key_t *private, chunk_t key, chunk_t iv, int oid, + */ + static bool remove_padding(private_pkcs7_enveloped_data_t *this) + { +- u_char *pos = this->content.ptr + this->content.len - 1; +- u_char pattern = *pos; +- size_t padding = pattern; ++ u_char *pos, pattern; ++ size_t padding; ++ ++ if (!this->content.len) ++ { ++ return FALSE; ++ } ++ ++ pos = this->content.ptr + this->content.len - 1; ++ pattern = *pos; ++ padding = pattern; + + if (padding > this->content.len) + { diff -Nru strongswan-5.9.8/debian/patches/0014-constraints-Case-insensitive-matching-and-reject-exc.patch strongswan-5.9.8/debian/patches/0014-constraints-Case-insensitive-matching-and-reject-exc.patch --- strongswan-5.9.8/debian/patches/0014-constraints-Case-insensitive-matching-and-reject-exc.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0014-constraints-Case-insensitive-matching-and-reject-exc.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,123 @@ +From: Tobias Brunner +Date: Mon, 23 Mar 2026 17:45:11 +0100 +Subject: constraints: Case-insensitive matching and reject excluded DN name + constraints + +The case is generally ignored when matching identities. So this is +an issue with excluded name constraints where a malicious intermediate +CA could evade the constraints by issuing certificates with names that +just modify the case (e.g. strongSwan.org instead strongswan.org). + +Note that it's likely that permitted name constraints are preferred over +excluded name constraints as it might be difficult to come up with a +conclusive list of names to exclude. + +With directoryName (DN) name constraints the issue is a bit more comples. +Some RDNs have to be matched in a case-insensitive manner, which we e.g. +do in `identification.c::rdn_equals`. By not doing it for name +constraints, a malicious intermediate CA could evade an excluded name +constraint just by modifying the case in such an RDN. + +While we could use the mentioned function in `dn_matches`, this doesn't +properly fix the problem because the function is basically too strict. +Especially in regards to RDNs of type UTF8String, which are only compared +binary. To match these properly, we'd have to implement the string +preparation described in RFC 5280, section 7.1 and the referenced RFCs. +Until that's the case, we reject excluded name constraints of type +directoryName as we are unable to enforce them. + +Fixes: a2b340764fac ("Implemented NameConstraint matching in constraints plugin") +Fixes: CVE-2026-35331 +--- + .../plugins/constraints/constraints_validator.c | 25 +++++++++++++++++++--- + src/libstrongswan/tests/suites/test_certnames.c | 10 ++++----- + 2 files changed, 27 insertions(+), 8 deletions(-) + +diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c +index 0f074c4..ade9b97 100644 +--- a/src/libstrongswan/plugins/constraints/constraints_validator.c ++++ b/src/libstrongswan/plugins/constraints/constraints_validator.c +@@ -52,6 +52,18 @@ static bool check_pathlen(x509_t *issuer, int pathlen) + return TRUE; + } + ++/** ++ * Check if the constraint and ID strings match case-insensitively ++ */ ++static bool string_matches(chunk_t constraint, chunk_t id) ++{ ++ /* make sure the two strings have actually the same length */ ++ return constraint.len == id.len && ++ memchr(constraint.ptr, 0, constraint.len) == NULL && ++ memchr(id.ptr, 0, id.len) == NULL && ++ strncasecmp(constraint.ptr, id.ptr, constraint.len) == 0; ++} ++ + /** + * Check if a FQDN constraint matches + */ +@@ -67,7 +79,7 @@ static bool fqdn_matches(identification_t *constraint, identification_t *id) + return FALSE; + } + diff = chunk_create(i.ptr, i.len - c.len); +- if (!chunk_equals(c, chunk_skip(i, diff.len))) ++ if (!string_matches(c, chunk_skip(i, diff.len))) + { + return FALSE; + } +@@ -98,10 +110,10 @@ static bool email_matches(identification_t *constraint, identification_t *id) + } + if (memchr(c.ptr, '@', c.len)) + { /* constraint is a full email address */ +- return chunk_equals(c, i); ++ return string_matches(c, i); + } + diff = chunk_create(i.ptr, i.len - c.len); +- if (!diff.len || !chunk_equals(c, chunk_skip(i, diff.len))) ++ if (!string_matches(c, chunk_skip(i, diff.len))) + { + return FALSE; + } +@@ -158,6 +170,13 @@ static bool name_constraint_matches(identification_t *constraint, + type = constraint->get_type(constraint); + if (type == ID_DER_ASN1_DN) + { ++ if (!permitted) ++ { ++ DBG1(DBG_CFG, "excluded %N NameConstraint not supported", ++ id_type_names, type); ++ /* we have to return TRUE to let the constraint fail */ ++ return TRUE; ++ } + matches = dn_matches(constraint, cert->get_subject(cert)); + if (matches != permitted) + { +diff --git a/src/libstrongswan/tests/suites/test_certnames.c b/src/libstrongswan/tests/suites/test_certnames.c +index 3672912..390f202 100644 +--- a/src/libstrongswan/tests/suites/test_certnames.c ++++ b/src/libstrongswan/tests/suites/test_certnames.c +@@ -232,11 +232,11 @@ static struct { + char *subject; + bool good; + } excluded_dn[] = { +- { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE }, +- { "C=CH, O=another", "C=CH, O=anot", TRUE }, +- { "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE }, ++ { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", FALSE }, ++ { "C=CH, O=another", "C=CH, O=anot", FALSE }, ++ { "C=CH, O=another", "C=CH, O=anot, CN=tester", FALSE }, + { "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE }, +- { "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE }, ++ { "C=CH, O=another", "C=CH, CN=tester, O=another", FALSE }, + }; + + START_TEST(test_excluded_dn) +@@ -334,7 +334,7 @@ static struct { + char *subject; + bool good; + } excluded_dninh[] = { +- { "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE }, ++ { "C=CH, O=strongSwan", "C=CH", "C=DE", FALSE }, + { "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE }, + { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE }, + }; diff -Nru strongswan-5.9.8/debian/patches/0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch strongswan-5.9.8/debian/patches/0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch --- strongswan-5.9.8/debian/patches/0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch 1970-01-01 00:00:00.000000000 +0000 +++ strongswan-5.9.8/debian/patches/0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch 2026-04-13 09:19:15.000000000 +0000 @@ -0,0 +1,246 @@ +From: Tobias Brunner +Date: Tue, 24 Mar 2026 18:00:23 +0100 +Subject: gmp: Avoid crash and timing leaks in PKCS#1 v1.5 decryption padding + validation +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +This fixes a potential crash due to a null-pointer dereference if rsadp() +returns NULL (e.g. with an all-zero ciphertext). + +And it also implements the PKCS#1 v1.5 decryption padding check in +constant time. + +The timing leak caused by the previous implementation was measured at +~17.5 μs at 3 GHz, which could allow a Bleichenbacher-like attack in +LAN environments. However, because of how RSA encryption is used in +strongSwan, this is not that much of an issue in practice. The mechanism +is only used for two use cases. One is SCEP/EST via PKCS#7 enveloped +data. Fortunately, this can not be triggered in significant numbers by +an attacker. The other use case is TLS as used by EAP methods (EAP-TLS, +EAP-PEAP/TTLS) during the authentication. While the cipher suites that +use RSA encryption are still enabled by default, the TLS messages are +wrapped in EAP and encrypted by IKE, making any kind of attack difficult. + +Note that the gmp plugin isn't enabled anymore by default. And even +before that, most setups had the openssl plugin enabled, which has +priority over the gmp plugin. So it's unlikely the plugin was used in +practice. + +Also note that this patch doesn't modify libstrongswan's Makefile.am +to avoid potentially requiring autotools when patching a tarball. + +Fixes: d615ffdcf3cd ("implement gmp_rsa_private_key.decrypt()") +Fixes: CVE-2026-35334 +--- + .../plugins/gmp/gmp_rsa_private_key.c | 54 +++++++---- + src/libstrongswan/utils/utils.h | 1 + + src/libstrongswan/utils/utils/constant_time.h | 103 +++++++++++++++++++++ + 3 files changed, 140 insertions(+), 18 deletions(-) + create mode 100644 src/libstrongswan/utils/utils/constant_time.h + +diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c +index 47784b6..7312fa9 100644 +--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c ++++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c +@@ -495,8 +495,8 @@ METHOD(private_key_t, decrypt, bool, + private_gmp_rsa_private_key_t *this, encryption_scheme_t scheme, + void *params, chunk_t crypto, chunk_t *plain) + { +- chunk_t em, stripped; +- bool success = FALSE; ++ chunk_t em; ++ u_int valid, i, j, found_sep = 0, sep_index = 0, m_index; + + if (scheme != ENCRYPT_RSA_PKCS1) + { +@@ -505,33 +505,51 @@ METHOD(private_key_t, decrypt, bool, + return FALSE; + } + /* rsa decryption using PKCS#1 RSADP */ +- stripped = em = rsadp(this, crypto); ++ em = rsadp(this, crypto); ++ if (em.len != this->k) ++ { ++ return FALSE; ++ } + +- /* PKCS#1 v1.5 8.1 encryption-block formatting (EB = 00 || 02 || PS || 00 || D) */ ++ /* PKCS#1 v1.5, RFC 8017, section 7.2.2 message structure: ++ * EM = 00 || 02 || PS || 00 || M */ + + /* check for hex pattern 00 02 in decrypted message */ +- if ((*stripped.ptr++ != 0x00) || (*(stripped.ptr++) != 0x02)) ++ valid = constant_time_eq(em.ptr[0], 0x00); ++ valid &= constant_time_eq(em.ptr[1], 0x02); ++ ++ /* the plaintext data starts after first 0x00 byte */ ++ for (i = 2; i < em.len; i++) + { +- DBG1(DBG_LIB, "incorrect padding - probably wrong rsa key"); +- goto end; ++ u_int zero = constant_time_eq(em.ptr[i], 0x00); ++ ++ sep_index = constant_time_select(i, sep_index, ~found_sep & zero); ++ found_sep |= zero; + } +- stripped.len -= 2; + +- /* the plaintext data starts after first 0x00 byte */ +- while (stripped.len-- > 0 && *stripped.ptr++ != 0x00) ++ /* make sure PS is at least eight bytes long (plus the initial bytes) */ ++ valid &= constant_time_ge(sep_index, 10); ++ ++ /* instead of copying the message directly, we try not to reveal the message ++ * length i.e. where the 0x00 byte was. and since clearing a chunk is ++ * relatively efficient, i.e. doesn't leak much, we always allocate and copy ++ * a value and then clear it if the structure was invalid */ ++ m_index = constant_time_select(sep_index + 1, 11, valid); + +- if (stripped.len == 0) ++ *plain = chunk_alloc(this->k); ++ for (i = 0, j = 0; i < em.len; i++) + { +- DBG1(DBG_LIB, "no plaintext data"); +- goto end; ++ plain->ptr[j] = em.ptr[i]; ++ j += constant_time_ge(i, m_index); + } ++ plain->len = j; + +- *plain = chunk_clone(stripped); +- success = TRUE; +- +-end: ++ if (!valid) ++ { ++ chunk_clear(plain); ++ } + chunk_clear(&em); +- return success; ++ return valid; + } + + METHOD(private_key_t, get_keysize, int, +diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h +index 083f553..2bc2f9a 100644 +--- a/src/libstrongswan/utils/utils.h ++++ b/src/libstrongswan/utils/utils.h +@@ -53,6 +53,7 @@ + #include "utils/atomics.h" + #include "utils/align.h" + #include "utils/byteorder.h" ++#include "utils/constant_time.h" + #include "utils/string.h" + #include "utils/memory.h" + #include "utils/strerror.h" +diff --git a/src/libstrongswan/utils/utils/constant_time.h b/src/libstrongswan/utils/utils/constant_time.h +new file mode 100644 +index 0000000..0c2c6a2 +--- /dev/null ++++ b/src/libstrongswan/utils/utils/constant_time.h +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (C) 2026 Tobias Brunner ++ * ++ * Copyright (C) secunet Security Networks AG ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. See . ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * for more details. ++ */ ++ ++/** ++ * @defgroup constant_time_i constant_time ++ * @{ @ingroup constant_time_i ++ */ ++ ++#ifndef CONSTANT_TIME_H_ ++#define CONSTANT_TIME_H_ ++ ++#include ++ ++/** ++ * Check if the given values are not equal in constant time. ++ * ++ * @param x first value to check ++ * @param y second value to check ++ * @return 1 if values are not equal, 0 otherwise ++ */ ++static inline u_int constant_time_neq(uint32_t x, uint32_t y) ++{ ++ return ((x-y) | (y-x)) >> 31; ++} ++ ++/** ++ * Check if the given values are equal in constant time. ++ * ++ * @param x first value to check ++ * @param y second value to check ++ * @return 1 if values are equal, 0 otherwise ++ */ ++static inline u_int constant_time_eq(uint32_t x, uint32_t y) ++{ ++ return 1 ^ constant_time_neq(x, y); ++} ++ ++/** ++ * Compare the two values and return 1 if the first argument is lower than ++ * the second in constant time. ++ * ++ * @param x first value to check ++ * @param y second value to check ++ * @return 1 if first value is lower than second ++ */ ++static inline u_int constant_time_lt(uint32_t x, uint32_t y) ++{ ++ return (x ^ ((x^y) | ((x-y) ^ y))) >> 31; ++} ++ ++/** ++ * Compare the two values and return 1 if the first argument greater or equal to ++ * the second in constant time. ++ * ++ * @param x first value to check ++ * @param y second value to check ++ * @return 1 if first value is greater or equal to the second ++ */ ++static inline u_int constant_time_ge(uint32_t x, uint32_t y) ++{ ++ return 1 ^ constant_time_lt(x, y); ++} ++ ++/** ++ * Return a 32-bit all bit-set mask if the given value is not 0. ++ * ++ * @param x value to check ++ * @return 0xffffffff if value is != 0, 0 otherwise ++ */ ++static inline uint32_t constant_time_mask(uint32_t x) ++{ ++ return -(uint32_t)constant_time_neq(x, 0); ++} ++ ++/** ++ * Select one of two values depending on whether the condition is != 0 or not. ++ * Basically equivalent to 'c ? x : y'. ++ * ++ * @param x first value to select ++ * @param y second value to select ++ * @param c condition ++ * @return x if c is != 0, y otherwise ++ */ ++static inline uint32_t constant_time_select(uint32_t x, uint32_t y, uint32_t c) ++{ ++ uint32_t m = constant_time_mask(c); ++ return (x & m) | (y & ~m); ++} ++ ++#endif /** CONSTANT_TIME_H_ @} */ diff -Nru strongswan-5.9.8/debian/patches/series strongswan-5.9.8/debian/patches/series --- strongswan-5.9.8/debian/patches/series 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/patches/series 2026-04-13 09:19:15.000000000 +0000 @@ -6,3 +6,10 @@ 0006-charon-tkm-Validate-DH-public-key-to-fix-potential-b.patch 0007-eap-mschapv2-Fix-length-check-for-Failure-Request-pa.patch 0008-eap-ttls-Prevent-crash-if-AVP-length-header-field-is.patch +0009-libsimaka-Reject-zero-length-EAP-SIM-AKA-attributes.patch +0010-libradius-Reject-undersized-attributes-in-enumerator.patch +0011-tls-server-Only-accept-non-empty-ECDH-public-keys-wi.patch +0012-tls-server-Prevent-infinite-loop-if-supported-versio.patch +0013-pkcs5-pkcs7-Avoid-NULL-pointer-dereference-when-veri.patch +0014-constraints-Case-insensitive-matching-and-reject-exc.patch +0015-gmp-Avoid-crash-and-timing-leaks-in-PKCS-1-v1.5-decr.patch diff -Nru strongswan-5.9.8/debian/po/cs.po strongswan-5.9.8/debian/po/cs.po --- strongswan-5.9.8/debian/po/cs.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/cs.po 2026-04-13 09:19:15.000000000 +0000 @@ -13,7 +13,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-28 14:42+0100\n" "Last-Translator: Miroslav Kure \n" "Language-Team: Czech \n" diff -Nru strongswan-5.9.8/debian/po/da.po strongswan-5.9.8/debian/po/da.po --- strongswan-5.9.8/debian/po/da.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/da.po 2026-04-13 09:19:15.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-06 12:42+0000\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" diff -Nru strongswan-5.9.8/debian/po/de.po strongswan-5.9.8/debian/po/de.po --- strongswan-5.9.8/debian/po/de.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/de.po 2026-04-13 09:19:15.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: strongswan 4.4.0-1\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-11-02 15:40+0100\n" "Last-Translator: Helge Kreutzmann \n" "Language-Team: German \n" diff -Nru strongswan-5.9.8/debian/po/es.po strongswan-5.9.8/debian/po/es.po --- strongswan-5.9.8/debian/po/es.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/es.po 2026-04-13 09:19:15.000000000 +0000 @@ -31,7 +31,7 @@ msgstr "" "Project-Id-Version: strongswan 4.4.1-5\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-12-17 17:19-0300\n" "Last-Translator: Matías Bellone \n" "Language-Team: Debian l10n Spanish \n" diff -Nru strongswan-5.9.8/debian/po/eu.po strongswan-5.9.8/debian/po/eu.po --- strongswan-5.9.8/debian/po/eu.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/eu.po 2026-04-13 09:19:15.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: strongswan_4.4.1-5.1_eu\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-15 21:41+0200\n" "Last-Translator: Iñaki Larrañaga Murgoitio \n" "Language-Team: Basque \n" diff -Nru strongswan-5.9.8/debian/po/fi.po strongswan-5.9.8/debian/po/fi.po --- strongswan-5.9.8/debian/po/fi.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/fi.po 2026-04-13 09:19:15.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2009-05-25 14:49+0100\n" "Last-Translator: Esko Arajärvi \n" "Language-Team: Finnish \n" diff -Nru strongswan-5.9.8/debian/po/fr.po strongswan-5.9.8/debian/po/fr.po --- strongswan-5.9.8/debian/po/fr.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/fr.po 2026-04-13 09:19:15.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2010-06-24 22:17+0200\n" "Last-Translator: Christian Perrier \n" "Language-Team: French \n" diff -Nru strongswan-5.9.8/debian/po/gl.po strongswan-5.9.8/debian/po/gl.po --- strongswan-5.9.8/debian/po/gl.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/gl.po 2026-04-13 09:19:15.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: templates_[kI6655]\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2009-05-25 14:50+0100\n" "Last-Translator: marce villarino \n" "Language-Team: Galician \n" diff -Nru strongswan-5.9.8/debian/po/it.po strongswan-5.9.8/debian/po/it.po --- strongswan-5.9.8/debian/po/it.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/it.po 2026-04-13 09:19:15.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-11-09 13:41+0200\n" "Last-Translator: Beatrice Torracca \n" "Language-Team: Italian \n" diff -Nru strongswan-5.9.8/debian/po/ja.po strongswan-5.9.8/debian/po/ja.po --- strongswan-5.9.8/debian/po/ja.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/ja.po 2026-04-13 09:19:15.000000000 +0000 @@ -16,7 +16,7 @@ msgstr "" "Project-Id-Version: strongswan 4.4.1-4\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-02-07 21:28+0900\n" "Last-Translator: Hideki Yamane \n" "Language-Team: Japanese \n" diff -Nru strongswan-5.9.8/debian/po/nb.po strongswan-5.9.8/debian/po/nb.po --- strongswan-5.9.8/debian/po/nb.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/nb.po 2026-04-13 09:19:15.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: nb\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-06 17:37+0200\n" "Last-Translator: Bjørn Steensrud \n" "Language-Team: Norwegian Bokmål \n" diff -Nru strongswan-5.9.8/debian/po/nl.po strongswan-5.9.8/debian/po/nl.po --- strongswan-5.9.8/debian/po/nl.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/nl.po 2026-04-13 09:19:15.000000000 +0000 @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: strongswan 4.5.0-1\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2014-09-24 18:39+0200\n" "Last-Translator: Frans Spiesschaert \n" "Language-Team: Debian Dutch l10n Team \n" diff -Nru strongswan-5.9.8/debian/po/pl.po strongswan-5.9.8/debian/po/pl.po --- strongswan-5.9.8/debian/po/pl.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/pl.po 2026-04-13 09:19:15.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2012-01-31 15:36+0100\n" "Last-Translator: Michał Kułach \n" "Language-Team: Polish \n" diff -Nru strongswan-5.9.8/debian/po/pt.po strongswan-5.9.8/debian/po/pt.po --- strongswan-5.9.8/debian/po/pt.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/pt.po 2026-04-13 09:19:15.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: strongswan 5.1.0-3\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-11-18 00:33+0000\n" "Last-Translator: Américo Monteiro \n" "Language-Team: Portuguese \n" diff -Nru strongswan-5.9.8/debian/po/pt_BR.po strongswan-5.9.8/debian/po/pt_BR.po --- strongswan-5.9.8/debian/po/pt_BR.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/pt_BR.po 2026-04-13 09:19:15.000000000 +0000 @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: strongswan 5.1.3-4\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2014-06-25 18:13-0300\n" "Last-Translator: Adriano Rafael Gomes \n" "Language-Team: Brazilian Portuguese \n" "Language-Team: Russian \n" diff -Nru strongswan-5.9.8/debian/po/sv.po strongswan-5.9.8/debian/po/sv.po --- strongswan-5.9.8/debian/po/sv.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/sv.po 2026-04-13 09:19:15.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: strongswan_sv\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-07 09:05+0100\n" "Last-Translator: Martin Bagge / brother \n" "Language-Team: Swedish \n" diff -Nru strongswan-5.9.8/debian/po/templates.pot strongswan-5.9.8/debian/po/templates.pot --- strongswan-5.9.8/debian/po/templates.pot 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/templates.pot 2026-04-13 09:19:15.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff -Nru strongswan-5.9.8/debian/po/tr.po strongswan-5.9.8/debian/po/tr.po --- strongswan-5.9.8/debian/po/tr.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/tr.po 2026-04-13 09:19:15.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: strongswan\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2013-10-24 11:17+0200\n" "Last-Translator: Atila KOÇ \n" "Language-Team: Türkçe \n" diff -Nru strongswan-5.9.8/debian/po/vi.po strongswan-5.9.8/debian/po/vi.po --- strongswan-5.9.8/debian/po/vi.po 2026-03-18 07:53:16.000000000 +0000 +++ strongswan-5.9.8/debian/po/vi.po 2026-04-13 09:19:15.000000000 +0000 @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: strongswan 4.4.0-1\n" "Report-Msgid-Bugs-To: strongswan@packages.debian.org\n" -"POT-Creation-Date: 2026-03-18 08:53+0100\n" +"POT-Creation-Date: 2026-04-13 11:19+0200\n" "PO-Revision-Date: 2010-10-03 19:22+1030\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n"