Commit Graph
4286 Commits
Author SHA1 Message Date
Tobias Brunner a26dd3da33 openssl: Check that EC keys don't have explicit params for internally loaded keys
Keys loaded via generic loader (KEY_ANY) or from a PKCS#12 file (or an
engine) don't go through the openssl_ec_private_key_load() constructor
that checks for explicit parameters.
2026-05-19 17:27:33 +02:00
Tobias Brunner ab19f691c7 botan: Fix registration of ECDSA signature/verification plugin features
This was broken since the Botan 3 release, which removed the EMSA1
class and the define.  The "EMSA1()" wrapper when signing/verifying is
technically not necessary anymore since then (it's deprecated but still
accepted).  But to still support Botan 2, we keep that in for now.
2026-05-19 17:27:33 +02:00
Tobias Brunner 8ff3238027 openssl: Prevent OpenSSL from using posix_memalign() if LD is enabled
The leak detective doesn't wrap this function and calling the original
causes unknown memory frees and even segmentation faults.  This is now
triggered with OpenSSL 4 as the implementation of ECP256 uses
OPENSSL_aligned_alloc_array().

Setting a custom memory functions forces OpenSSL to implement aligned
allocations internally, using the registered allocation function.
2026-05-06 10:46:43 +02:00
Tobias Brunner 374b17fe88 openssl: Fix 'const' issues that came up with OpenSSL 4 2026-05-06 10:46:43 +02:00
Tobias Brunner 528e5f07c3 openssl: Use functions for ASN.1 struct members hidden in OpenSSL 4
According to the docs, most ASN.1 types are just typedefs of ASN1_STRING.
2026-05-06 10:46:43 +02:00
Thomas Egerer 82c01b7060 openssl: Use openssl_i2chunk when creating ASN.1 chunks
Using the return value of i2d_* directly as input of chunk_alloc imposes
the risk of creating an invalid chunk when the return value of the i2d_*
function is -1. The openssl_i2chunk macro is meant to avoid this.

Signed-off-by: Thomas Egerer <[email protected]>
2026-05-06 10:46:43 +02:00
Tobias Brunner 0a64c27a1f constant-time: Fix Doxygen group assignment 2026-04-23 11:46:52 +02:00
Tobias Brunner b4ba8a6fb5 openssl: Fix memory leak if ipAddrBlock is non-canonical 2026-04-22 14:12:12 +02:00
Tobias Brunner e2fa67e8fc gmp: Avoid crash and timing leaks in PKCS#1 v1.5 decryption padding validation
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.

Fixes: d615ffdcf3 ("implement gmp_rsa_private_key.decrypt()")
Fixes: CVE-2026-35334
2026-04-21 16:48:56 +02:00
Tobias Brunner 90fd268088 utils: Add constant-time comparison primitives for uint32_t 2026-04-21 16:48:56 +02:00
Tobias Brunner 8dae5605a7 pkcs7: Avoid NULL pointer dereference when verifying padding in enveloped content
As the previous issue, this can be triggered via IKEv1 CERT payloads.

Fixes: d7aa09104f ("Implement PKCS#7 enveloped-data parsing and decryption")
Fixes: CVE-2026-35329
2026-04-21 16:48:56 +02:00
Tobias Brunner c6a2185c42 pkcs5: Fail decryption if data is empty
This avoids the previous bug early.
2026-04-21 16:48:56 +02:00
Tobias Brunner 4da84019cc pkcs5: Avoid NULL pointer dereference when verifying padding
Can be triggered via empty PKCS#7 encrypted content in IKEv1 CERT payload.

Fixes: 4076e3ee91 ("Extract PKCS#5 handling from pkcs8 plugin to separate helper class")
Fixes: CVE-2026-35329
2026-04-21 16:48:56 +02:00
Tobias Brunner 64130ede5c constraints: Reject excluded directoryName (DN) name constraints
There is an issue similar to the one fixed with the previous commit when
using directoryName (DN) name constraints.  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: a2b340764f ("Implemented NameConstraint matching in constraints plugin")
Fixes: CVE-2026-35331
2026-04-21 16:48:56 +02:00
Tobias Brunner c66143db48 constraints: Match FQDN and email addresses case-insensitively
The case is generally ignored when matching such 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.

Fixes: a2b340764f ("Implemented NameConstraint matching in constraints plugin")
Fixes: CVE-2026-35331
2026-04-21 16:48:56 +02:00
Markus Theil c60a14ba23 botan: Fix typo in algorithm string for SHA3-224 RSA verification
Signed-off-by: Markus Theil <[email protected]>
2026-04-13 15:46:45 +02:00
Markus Theil e1091327b5 tun-device: Also close IPv6 socket on destruction
Signed-off-by: Markus Theil <[email protected]>
2026-04-13 15:13:14 +02:00
Markus Theil fdd06d99ec botan: Make RNG types configurable
This allows for usage of ESDM or jitterentropy as Botan RNG without
patching strongSwan.

Signed-off-by: Markus Theil <[email protected]>
2026-04-13 15:12:31 +02:00
Tobias Brunner 99e9db478d unit-tests: Use longer input for ECDSA tests
wolfSSL 5.9.1 starts to enforce a minimum (and maximum) length for the
hash when signing.  Since we'll always require SHA-1, use 20 bytes as
input in the tests to succeed with SIGN_ECDSA_WITH_NULL.
2026-04-09 09:53:36 +02:00
Tobias Brunner 05807b1b1b openssl: Handle EdDSA keys from engines special again
Fixes: 052a939553 ("openssl: Add support for Ed25519 via AWS-LC")
2026-04-02 08:17:05 +02:00
Tobias Brunner 7b0190cb26 revocation: Fix memory leak if nonce in OCSP response doesn't match 2026-04-02 08:17:04 +02:00
Tobias Brunner 06e5462a4b credential-factory: Enforce an upper limit when creating nested credentials
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.
2026-04-02 08:16:07 +02:00
Tobias Brunner 3c637c7521 openssl: Fix return value if returning EdDSA public key fails 2026-04-01 19:33:09 +02:00
Tobias Brunner 358653d06a gmp: Reject public keys with public exponent e < 3
This ensures that we don't load a key with e=1, which basically renders
RSA into a no-op.  Since keys are universally generated with e=65537 and
no reputable CA will sign keys with e=1, allowing this before didn't have
any real world impact.
2026-03-13 09:28:32 +01:00
Dustin Kirkland d6b1574e2a string: Fix -Werror=discarded-qualifiers with GCC 15
GCC 15 tightened its built-in declarations for strchr() and strstr() so
that they now propagate const from their first argument, triggering
-Werror=discarded-qualifiers on three assignments in string.c:

  translate():
    char *match = strchr(from, *pos)
    `from` is const char *, so the result of strchr() is const char *.
    `match` is only used for pointer arithmetic (match - from), so
    declaring it const char * is correct and safe.

  strreplace():
    found = strstr(str, search)         [line ~73]
    found = strstr(pos, search)         [line ~89, while condition]
    `str`/`pos` are derived from a const char * parameter, so strstr()
    returns const char *. `found` is used as a mutable char * later
    (pos = found + slen), consistent with the existing (char*) casts
    already used throughout this function for the same reason.
    Add explicit (char*) casts to match the established pattern.

Closes strongswan/strongswan#3015
2026-03-04 16:28:56 +01:00
Tobias Brunner 589c74009b stream: Clarify that some methods must not be called from callbacks 2026-02-20 12:44:55 +01:00
Tobias Brunner f10b9adec9 ipsec-types: Add a proper hash function for ipsec_sa_cfg_t
While 3c12905103 ("ipsec: Add function to compare two ipsec_sa_cfg_t
instances") added a comparison function to avoid issues with non-zeroed
padding, hashes were still calculated using chunk_hash().
2026-02-12 14:23:44 +01:00
Tobias Brunner 0d41001e74 debug: Add helper to get the current default log level for a group 2026-02-06 11:21:34 +01:00
Tobias Brunner dd7b0283ef plugin-loader: Add option to change log message if plugin is not found
Distributions like Debian/Ubuntu ship the plugins in multiple packages
that are not all installed by default.  When running tools like pki or
swanctl, which don't use modular loading with config snippets by default,
there are errors in the output if these packages and plugins are
currently not available.  In order to not alarm users, this change adds
a configure option that package maintainers can use.  It causes the log
level of the message to increase and also adds a note that mentions that
plugins are potentially available in other packages (which should be the
case unless the user tried to load a plugin, e.g. via load statement,
that is not actually built and shipped by the package maintainers).
2026-02-06 11:21:34 +01:00
Tobias Brunner b8d8277ae0 stream-service-unix: Remove unnecessary execute permission from sockets
References strongswan/strongswan#2983
2026-02-06 11:17:36 +01:00
Tobias Brunner 7fa4d54b3c array: Handle recursive calls to array_sort() if qsort_r() is not supported
Such a recursive call occurs when sorting the array of Child SAs inside
an IKE SA that causes comparisons of the child configs and their
proposals, which in turn creates a merged array of all transform types
and that uses array_sort() and array_bsearch().

Closes strongswan/strongswan#2926

Fixes: 8e7f379f71 ("ike-sa: Sort CHILD_SAs by CPU ID")
2026-01-22 18:14:58 +01:00
Tobias Brunner d68044b216 identification: Add support for organizationIdentifier in DNs
These are e.g. used in eIDAS certificates.
2026-01-05 10:50:24 +01:00
Tobias Brunner f79504994a agent: Fix compiler warning when building with clang
Fixes: 8b467ad39a ("agent: Add option to open socket as specific user")
2025-12-12 15:59:38 +01:00
Tobias Brunner d20a0116b2 Use Botan 3.10.0 for tests
Clean up leak-detective whitelist for newer Botan versions but add
`botan_private_key_load` as `botan_privkey_load*` won't show up anymore
without bfd-backtraces due to inlining if we don't call it directly.

Ref: https://github.com/randombit/botan/discussions/4868
2025-12-12 15:58:31 +01:00
Tobias Brunner 8b467ad39a agent: Add option to open socket as specific user
This can prevent an attack where user A passes the path to user B's
ssh-agent socket to the daemon that is running as root.
2025-12-10 18:34:19 +01:00
Jean-François Hren f25b1aca8b credential-manager: Fix leaked signature params if self-signed cert is untrusted
Closes strongswan/strongswan#2954
2025-12-01 19:18:53 +01:00
Tobias Brunner 9fe4f9fc9f settings: Increase buffer size for key patterns/parts when looking up settings
The buffer size for individual parts of a key now match the maximum length
of names in VICI. The full pattern should accommodate several long names
(e.g. for connections and child connections in swanctl) even if no
printf-specifiers are used.
2025-11-19 10:37:55 +01:00
Martin Willi df6977d4cf revocation: Block only one thread per URL after a previous CRL fetch failed
If a CRL server is unresponsive, all threads trying to fetch this CRL will
block execution. If a recent previous attempt to fetch the CRL failed, it
is likely that it will fail again. While it makes sense to retry fetching
the CRL on demand with one thread, it hardly does to block additional
threads while the first one is blocked during the fetch.

So remember the timestamp of the last CRL fetch failure per URL, and do
not block more than one thread in the CRL fetch for some time. This time
is a multiple of the configured fetch timeout, so that it works well for
any configured value. With the default configuration, a failing CRL fetch
will impact concurrent CRL fetches for the same URL for 30s.
2025-11-13 18:15:15 +01:00
Martin Willi 330a7d1963 revocation: Synchronize CRL fetches of multiple threads to the same URL
When handling many connection attempts from peers using the same CA, a slow
or non-responsive CRL distribution point can lead to concurrent fetches of
the same CRL by multiple threads. This is not only inefficient, but results
in all threads blocking for the full fetch timeout, potentially blocking
all threads in the pool.

As a first step, synchronize CRL fetches using a global mutex and a per-URL
condvar, so threads can wait for the CRL if another is already fetching it.
This reduces the number of useless concurrent CRL fetches, and allows threads
joining the party late to get blocked only until the first fetch completes
or times out.

The URL entry is preserved in the hashtable after completing the fetch.
This will allow subsequent optimizations to store the last fetch result
and act accordingly. The CRL itself is not, as CRLs can be rather large
and caching them can be done using existing mechanisms controlled via
corresponding options.
2025-11-13 18:15:15 +01:00
Martin Willi 119dfc2c38 revocation: Move CRL/OCSP fetch operations to a dedicated fetcher helper
Before adding stateful CRL fetching extensions, refactor CRL fetching to
a helper class for better separation. While there are currently no plans
to extend OCSP fetching, move it as well for consistency.
2025-11-13 18:15:15 +01:00
Martin Willi f739f7a075 revocation: Pass "this" parameter along CRL/OCSP verification functions
As future commits will require shared state during fetch operations, a common
context is required. So pass along the "this" parameter in various revocation
functions.
2025-11-13 18:15:15 +01:00
Tobias Brunner 7c74925fa1 pkcs11: Fix comment
Fixes: e9fa338e23 ("pkcs11: Improve detection of already unwrapped CKA_EC_POINTs")
2025-10-17 17:20:13 +02:00
Tobias Brunner b3011e8e87 Remove support for MD2
No part of IKE/IPsec or X.509 uses MD2 anymore, so there really is no
reason to still support it (unlike MD4 that is used in EAP-MSCHAPv2,
MD5 that's used in EAP-MD5, or SHA-1 that's used for e.g. NAT-D hashes).

It caused test vectors to fail on systems where OpenSSL is built with
MD2 support but has it disabled at runtime.
2025-09-23 15:59:35 +02:00
Tobias Brunner 0e768233f2 leak-detective: Include OpenSSL symbol seen on Debian trixie 2025-09-18 11:13:32 +02:00
Tobias Brunner ac0272cad1 host: Don't try to resolve %any* keywords with mismatched address family
While host_create_from_string_and_family() usually replaces %any*
keywords, this fails if the address family doesn't match (e.g. %any4 with
AF_INET6).  There is no point in trying to resolve these keywords via
DNS as % is no valid character for host names.

Closes strongswan/strongswan#2880
2025-09-16 10:14:26 +02:00
Tobias Brunner 45f5a7a698 curl: Fix types enforced by compiler check in newer libcurl headers 2025-09-15 16:51:42 +02:00
Tobias Brunner c4b32aab04 plugin-loader: Check version of loaded plugins
This prevents loading plugins from older builds that can cause all sorts
of issues as they might access struct members in different locations.

We don't check the version for statically linked plugins.
2025-08-22 15:32:39 +02:00
Tobias Brunner 5cab5672e7 Define plugin version in all existing plugins 2025-08-22 15:32:39 +02:00
Tobias Brunner d087c349b4 plugin: Add macro to define plugin version and constructor 2025-08-22 15:32:39 +02:00
Tobias Brunner 1b551a9bfd plugin-loader: Don't prevent dynamic linking in addition to static constructors
When built with static plugins and constructors, we might still want to
be able to load external plugins.

Fixes: d860c26e95 ("plugin-loader: Properly support compilation without dlopen()/dlsym() etc.")
2025-08-22 15:32:39 +02:00