The HKDF-Expand() function defined in RFC 5869 is basically the same as
IKEv2's prf+(), so we can use the former to implement the latter.
However, we can only support HMAC-based PRFs this way, which should be
fine as others are rarely used.
This adds support for labeled IPsec with SELinux (and a proprietary mode
that can be used to match child configs). For SELinux support, compile
with --enable-selinux.
Other changes include a combined start action (trap|start), avoiding
initiating duplicate CHILD_SAs, updating reqids if dynamic traffic
selectors change, removing reqid errors on policy updates, or querying
specific CHILD_SAs with vici's list-sas command.
Closes#3075
After establishing an IKE_SA, we check if any of its child configs
define generic SELinux labels and install trap policies for them if
necessary narrowed to the current (virtual) IPs.
This allows managing trap policies outside of the trap manager.
We'll use this to create trap policies with generic labels if trap policies
can't (or won't) be used (e.g. as responder for roadwarriors).
If update_sa() is called and dynamic traffic selectors are changed using
new addresses, this might cause issues if we continue to use a reqid that
doesn't match the updated traffic selectors. For instance, if the initiator
then uses make-before-break reauth from the new IP. It's also a particular
problem in the SELinux case where multiple CHILD_SAs with specific labels
all share the same (trap) policy with generic label. However, SAs created
after the update would not match due to the new reqid.
This was originally added with 1551d8b13d14 ("kernel-netlink: reject
policy refcount if the reqid differs"). Since then we added code to
allocate constant reqids for the same TS, which pretty much avoids the
previous issues.
However, the reqid might have to be changed due to MOBIKE updates. And
because reqids are allocated for a complete set of traffic selectors and
not individual pairs, this can create a problem with drop policies as
those will use the old reqid (they are installed with the same priority,
reqid etc. to replace the actual IPsec policies), while unmodified
replacement policies will use the new one. A similar issue exists for
CHILD_SAs with SELinux contexts as those all use duplicate policies (same
generic label) but can't all be updated concurrently.
With SELinux and without a specific label from an acquire, we abort
establishing the CHILD_SA (for the first one we prefer a childless IKE_SA,
but since that's a separate extension, we fall back to letting the initial
CHILD_SA fail as we won't propose a label).
If trap policies are not installed already (e.g. because it's impossible to
do so like as responder for roadwarriors), this will require installing
them dynamically once the IKE_SA is established.
In SELinux mode we install the configured label on the policies and the
negotiated one on the SAs. This is how it usually is configured where the
policy/configuration has a generic context and the SAs will get the actual
context of the flows assigned (the latter matches the former, so flows
match the policies but will trigger an acquire if no matching SA exists).
In the simple mode we don't pass the label to the kernel and to avoid
duplicate policy errors we also don't use it to acquire unique reqids.
The security labels can be retrieved in a separate list from the
regular traffic selectors. We currently only plan to support a single
security label ourselves, so when generating we don't expect a list.
Changes how regular address range traffic selectors are parsed as the
IKE parser currently doesn't provide sub-type parsing.
Also removed a lot of unused method definitions.