Instead of just generating an authorityKeyIdentifier based on the
issuer's public key, this allows CA certificates to be issued by a
different tool that doesn't use a SHA-1 hash of the subjectPublicKey
for the subjectKeyIdentifier.
Closesstrongswan/strongswan#1992
References strongswan/strongswan#1975
This allows preventing peers from authenticating with certificates
that are locally trusted, in particular, our own local certificate (which
safeguards against accidental reuse of certificates on multiple peers).
On the other hand, if this option is enabled, end-entity certificates
for peers can't be configured anymore explicitly (e.g. via remote.certs
in swanctl.conf).
These are not allowed in X.509 certificates according to RFC 5480 and
some newer validations apparently explicitly check for this.
Note that WolfSSL rejects such keys, by default. Only when compiled with
WOLFSSL_NO_ASN_STRICT are they accepted.
We can't actually explicitly listen for errors by passing POLLERR in
`events` (the man page for poll() clearly states it's ignored). On the
other hand, POLLERR can be returned for any FD and, even worse, it might
be the only event indicated.
The latter caused an infinite loop as we didn't notify the callback nor
clear the error by calling `getsockopt(..., SOL_SOCKET, SO_ERROR, ...)`.
And while the latter would be able to reset the state to break the loop,
it seems to leave the FD in a defunct state where no further events will
be returned by poll(). Notifying the callback works better (the error
is then reported by e.g. recvfrom()) and automatically happened already
if POLLERR was returned together with e.g. POLLIN.
So we now treat POLLERR like the other error indicators we handle (POLLHUP
and POLLINVAL) and just notify the callbacks.
The all-zero Ed25519 public key is rejected by botan_pubkey_check_key()
when the key is loaded.
Note that Botan 3 requires GCC 11 or CLANG 14, i.e. can't easily be built
on Debian bullseye or Ubuntu 20.04.
The thread-local storage function gets flagged via various botan FFI
functions when using Botan 3, whitelist that instead of all of them.
The previous code was problematic if a certificate request for a known
but unrelated CA was received and the local trust chain was incomplete.
Due to the received anchor, the incomplete trust chain was dismissed and
any intermediate CA certificates were, therefore, not sent to the peer.
This new approach doesn't dismiss an incomplete trust chain, but prefers
one that can be resolved to a received anchor. If no such chain is found,
the first one is used.
Some variables that are only assigned to be used in DBG statements
will otherwise trigger a "set but not used" warning/error if DEBUG_LEVEL
is too low.
Exiting the loop previously could cause watcher to busy wait (i.e.
rebuild the array and call poll() repeatedly) until the active callback
was done.
Assume watcher observes two FDs 15 and 22, which are in the list in that
order. FD 15 is signaled and its callback gets triggered. The array of
FDs is rebuilt and does not include 15 anymore. Now FD 22 is ready for
reading. However, when enumerating all registered FDs, the loop previously
was exited when reaching FD 15 and seeing that it's active. FD 22 was
never checked and the array was immediately rebuilt and poll() called.
If the callback for 15 took longer, this was repeated over and over.
This basically reverts d16d5a245f ("watcher: Avoid queueing multiple
watcher callbacks at the same time"), whose goal is quite unclear to me.
If it really wanted to allow only a single callback for all FDs, it didn't
achieve that as any FD before an active one would get notified and if
multiple FDs are ready concurrently, they'd all get triggered too.
Skipping entries with active callback makes sense as it avoids a lookup
in the FD array and subsequent revents checks. But why would we need to
rebuild the array if we see such an entry? Once the callback is done,
the watcher is notified and the array rebuilt anyway (also if any other
FD was ready and jobs get queued).
The list of FDs is recreated quite often (e.g. due to the kernel-netlink
event sockets) and if a logger depends on watcher_t in some way this
might cause conflicts if the mutex is held.
Since the same FD may be added multiple times (e.g. with separate
callbacks for WATCHER_READ and WATCHER_WRITE), the previous check
might not have found the correct entry. As the entry can't be removed
while in a callback, the pointer comparison is fine.
This could be problematic in case loggers in some way rely on watcher_t
themselves. This particular log message should rarely occur if at all,
but still avoid holding the mutex.