The RFC only allows that the number of fragments increases (if the
sender reduces the MTU).
Not enforcing this before could cause early reassembly as the trigger was
that the number of received fragments matches the total count of the
current packet (which was a bit weird anyway). Only an active MITM could
trigger this as individual fragments are encrypted and authenticated.
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.
If nothing was read from the message, the previous code could result in
a crash depending on where `ext.ptr` pointed to, as determined by the
current stack contents. Since TLS 1.3 is still disabled by default and
this is usually used for TLS-based EAP methods after validating the
IKEv2 server's certificate, the real world impact seems relatively low.
Fixes: 9ef46cfaf9 ("tls-peer: Mutual authentication support for TLS 1.3")
These attributes contain a 16-bit length field for the actual length of
the data in bits or bytes, as compared to the length in 4-byte blocks in
the attribute header. The previous code didn't correctly account for the
length of the fixed header (4 bytes) when it compared the parsed length
to the length in the header. This could cause an out-of-bounds read of
up to four bytes beyond the end of the attribute/message.
Fixes: f8330d0395 ("Added a libsimaka library with shared message handling code for EAP-SIM/AKA")
The length field in the AVP header includes the 8 bytes of the header
itself. Not checking for that and later subtracting it causes an
integer underflow that usually triggers a crash when accessing a
NULL pointer that resulted from the failing chunk_alloc() call because
of the high value.
The attempted allocations for invalid lengths (0-7) are 0xfffffff8,
0xfffffffc, or 0x100000000 (0 on 32-bit hosts), so this doesn't result
in a buffer overflow even if the allocation succeeds.
Fixes: 79f2102cb4 ("implemented server side support for EAP-TTLS")
Fixes: CVE-2026-25075
To make the default strongswan.conf, with `load_modular` enabled, work
if charon itself is not built, we enable generating the charon-specific
snippets also for the two other daemons that fall back on reading
options from the `charon` section.
Due to the static build, libcharon will depend on libradius as soon as
eap-radius is enabled even if not actually used. So in order to avoid
breaking the build of fuzz_ike when enabling this in CIFuzz, enable
it now before adding the actual fuzzer.
Closesstrongswan/strongswan#3028
Signed-off-by: Arthur Chan <arthur.chan@adalogics.com>
VICI_END (7) shouldn't be encoded in a message. However, if we encounter
it, we should at least set `out` accordingly so callers can abort the
enumeration. By not doing so previously and returning TRUE, callers
might access the possibly uninitialized name/value arguments passed to
the enumerator.
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.
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.
Closesstrongswan/strongswan#3015
Calling stream_t::destroy from the stream_t::on_read callback will
block the thread in watcher_t::remove because the FD is currently "in
callback". A similar issue was fixed in the lookip plugin with
961409b668 ("lookip: Disconnect asynchronously to avoid dead-locking
watcher unregistration").
Fixes: 85ebf6abd4 ("whitelist: Add error handling to socket reads and fix a memory leak")
This doesn't really seem useful (perhaps it was before we started to
configure the outbound interface on our routes). And it can actually
cause the route installation to fail e.g. for routes over point-to-point
interfaces where we'd get "Error: Nexthop has invalid gateway" errors.
Note that we can't return NULL if we find an interface as e.g. the updown
plugin uses this method to determine the outbound interface (it ignores
the nexthop), which it passes to the script. If we returned NULL, it
would pass "unknown" instead, which would cause the firewall rules to
mismatch. While it seems that 0.0.0.0/:: is ignored as nexthop by the
kernel on the installed route, I still explicitly ignore such addresses
to avoid any unintended side-effects.
The automatic route installation in the ikev2/shunt-manual-prio scenario
had to be disabled on the clients. The reason is that the route in table
220 won't have a nexthop set (the peers are directly connected), so when
trying to reach alice or venus via SSH, which matches the port-specific
bypass policies for which we don't install throw routes, the hosts will
do ARP requests for the target IPs instead of routing the packets via
moon.
Closesstrongswan/strongswan#2548
The action causes errors because it is not compatible to the Docker
version used in the runner images. Unfortunately, it doesn't seem
maintained anymore. The action is simple enough, though, so instead of
switching to a fork, we just use "docker run" directly.
Adds support for ICMP error forwarding that the kernel supports properly
since v6.9 (it still sends locally generated errors from the wrong source
IP, though).
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().
If a CHILD_SA is rekeyed using a CREATE_CHILD_SA request, a subsequent
DELETE for the old CHILD_SA may time out. Before sending this DELETE,
a CHILD_REKEYED state CHILD_SA set from child_rekey::process_i() is
immediately set to CHILD_DELETING from child_delete::build_i(). If the
IKE_SA dies due to a retransmission timeout of this DELETE, a redundant
child-down event is issued for the rekeyed CHILD_SA that has already seen a
child-rekey event.
A reproducer shows the following log and events:
[CFG] vici rekey CHILD_SA #533
[IKE] establishing CHILD_SA XXX{534} reqid 20
[ENC] generating CREATE_CHILD_SA request 0 [ N(REKEY_SA) SA No KE TSi TSr ]
[ENC] parsed CREATE_CHILD_SA response 0 [ SA No TSi TSr ]
[IKE] rekeyed CHILD_SA XXX{533} with SPIs ca997de6_i cd27d4fe_o with XXX{534} with SPIs ced1cd01_i c460a7c9_o
Event: child-rekey
[OLD SA] state: REKEYING, spi-in: ca997de6
[NEW SA] state: INSTALLED, spi-in: ced1cd01
[IKE] closing CHILD_SA XXX{533} with SPIs ca997de6_i (352 bytes) cd27d4fe_o (264 bytes) and TS 0.0.0.0/0 === 10.11.9.40/29
[IKE] sending DELETE for ESP CHILD_SA with SPI ca997de6
[ENC] generating INFORMATIONAL request 1 [ D ]
[IKE] retransmit 1 of request with message ID 1
[IKE] retransmit 2 of request with message ID 1
[IKE] retransmit 3 of request with message ID 1
[IKE] retransmit 4 of request with message ID 1
[IKE] giving up after 4 retransmits
Event: child-updown
[SA] state: DELETING, spi-in: ca997de6
Event: child-updown
[SA] state: INSTALLED, spi-in: ced1cd01
To prevent the redundant child-down event for the successfully rekeyed CHILD_SA,
check if a DELETING CHILD_SA has already removed its outbound state due to
having been rekeyed before issuing the child-down event.
Add a new exchange test exercising that a delete timeout after rekeying does
not cause a duplicate child-down event.
Uses a separate default plugin list for swanctl (instead of just loading
all of libstrongswan's plugins) to avoid some side-effects of loaded but
unused plugins. The load statements in the regression tests have been
updated accordingly.
A new configure option for maintainers of distributions that ship
plugins in separate packages changes the message if a plugin is not
found and reduces its log level. This confused users of tools that don't
use modular plugin loading (e.g. pki or swanctl).
Also changes command line handling in pki and swanctl so that the shared
options can be passed before the actual command and that the debug level
also affects library/plugin initialization.
References strongswan/strongswan#2971