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.
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.
We don't have any information on the issuer of cached OCSP responses, in
particular if the OCSP response is issued by a dedicated OCSP signer,
whose certificate might not be contained in the response or even signed
by the same CA but could just be locally installed. So the only way to
determine if a response applies to the current certificate and its CA
is searching for the response's issuer certificate and verifying that.
However, when using multiple CAs that provide revocation checking via
OCSP, in particular with multi-level CAs (e.g. like the
ikev2-multi-ca/ocsp-signers test scenario), we might have unrelated OCSP
responses in the cache when verifying a particular certificate. In this
case we don't need any confusing
ocsp response verification failed, no signer certificate '...' found
error messages because the response was for a different CA.
Similarly, if lots of clients of the same CA connect there could be lots
of OCSP responses in the cache that, while being applicable to the current
CA, don't have any information on the certificate we are currently
checking. In this case all the
ocsp response correctly signed by "..."
ocsp response contains no status on our certificate
messages don't provide any value.
In the mentioned test scenario, we suppress the
ocsp response verification failed, no signer certificate 'C=CH, O=strongSwan Project, OU=Research OCSP Signing Authority, CN=ocsp.research.strongswan.org' found
message from the cached OCSP response for carol's end-entity certificate
when verifying the "Research" intermediate CA certificate that issued
carol's certificate.
Then the
ocsp response verification failed, no signer certificate 'C=CH, O=strongSwan Project, OU=Research OCSP Signing Authority, CN=ocsp.research.strongswan.org' found
ocsp response verification failed, no signer certificate 'C=CH, O=strongSwan Project, OU=OCSP Signing Authority, CN=ocsp.strongswan.org' found
messages from the cached OCSP responses for carol's end-entity and
intermediate CA certificates when verifying dave's end-entity certificate.
And finally the
ocsp response verification failed, no signer certificate 'C=CH, O=strongSwan Project, OU=Research OCSP Signing Authority, CN=ocsp.research.strongswan.org' found
ocsp response correctly signed by "C=CH, O=strongSwan Project, OU=OCSP Signing Authority, CN=ocsp.strongswan.org"
ocsp response contains no status on our certificate
ocsp response verification failed, no signer certificate 'C=CH, O=strongSwan Project, OU=Sales OCSP Signing Authority, CN=ocsp.sales.strongswan.org' found
messages from the cached OCSP responses for carol's end-entity
certificate, the applicable but unrelated response for carol's "Research"
intermediate CA certificate and the response for dave's end-entity
certificate when verifying dave's "Sales" intermediate CA.
The x509 plugin retrieves serial numbers with two's complement
encoding whereas the openssl plugin partially returns them without
leading zeroes.
Serial numbers in X.509 certificates, X.509 CRL, X.509 attribute
certificates, OCSP Requests and OCSP responses are now returned in
canonical form without prepended zero octets.
Malicious servers could otherwise block the fetching thread indefinitely
after the initial TCP handshake (which has a default timeout of 10s
in the curl and winhttp plugins, the soup plugin actually has a default
overall timeout of 10s).
Commit 27756b081c (revocation: Check that nonce in OCSP response matches)
introduced strict nonce validation to prevent replay attacks with OCSP
responses having a longer lifetime. However, many commercial CAs (such as
Digicert) do not support nonces in responses, as they reuse once-issued OCSP
responses for the OCSP lifetime. This can be problematic for replay attack
scenarios, but is nothing we can fix at our end.
With the mentioned commit, such OCSP responses get completely unusable,
requiring the fallback to CRL based revocation. CRLs don't provide any
replay protection either, so there is nothing gained security-wise, but may
require a download of several megabytes CRL data.
To make use of replay protection where available, but fix OCSP verification
where it is not, do nonce verification only if the response actually contains
a nonce. To be safe against replay attacks, one has to fix the OCSP responder
or use a different CA, but this is not something we can enforce.
Fixes#3557.
If the certificate is revoked, we immediately returned and the chain was
invalid, however, if we couldn't fetch the CRL that result was not stored
for intermediate CAs and we weren't able to enforce a strict CRL policy
later.
Using such CRLs can be a problem if the clock on the host doing the
revocation check is trailing behind that of the host issuing CRLs in
scenarios where expired certificates are removed from CRLs. As revoked
certificates that expired will then not be part of new CRLs a host with
trailing clock might still accept such a certificate if it is still
valid according to its system clock but is not contained anymore in the
not yet valid CRL.
Depending on the plugins that eventually parse the certificate and CRL,
serials with MSB set (i.e. negative numbers that have a zero byte prefixed
when encoded as ASN.1 INTEGER) might have (x509 plugin) or not have
(openssl plugin) a zero byte prefix when returned by get_serial() or
enumerated from the CRL. Strip them before doing the comparison or
revocation checking might fail if not both credentials are parsed by the
same plugin (which should be rare and only happen if parsing of either
cert or CRL fails with one of the plugins and there is a fallback to the
implementation provided by the other plugin).
Fixes#2509.
These options disable validation as such, e.g. even from cached CRLs, not
only the fetching. Also made the plugin's validate() implementation a
no-op if both options are disabled.
Since the textual representation for a CRL is now standardized
in RFC 7468 one could argue that we should accept that too, even
though RFC 5280 explicitly demands CRLs fetched via HTTP/FTP to
be in DER format. But in particular for file URIs enforcing that
seems inconvenient.
Fixes#1203.
To avoid considering each cached OCSP response and evaluating its trustchain,
we limit the certificates considered for OCSP signing to:
- The issuing CA of the checked certificate
- A directly delegated signer by the same CA, having the OCSP signer constraint
- Any locally installed (trusted) certificate having the OCSP signer constraint
The first two options cover the requirements from RFC 6960 2.6. For
compatibility with non-conforming CAs, we allow the third option as exception,
but require the installation of such certificates locally.
This behavior was introduced with 6840a6fb to avoid key/signature strength
checking for the revocation trustchain as we do it for end entity certificates.
Unfortunately this breaks CA constraint checking under certain conditions, as
we merge additional intermediate/CA certificates to the auth config.
As key/signature strength checking of the revocation trustchain is a rather
exotic requirement we drop support for that to properly enforce CA constraints.
Certificates which are set on hold in a CRL might be removed from any
subsequent CRL. Hence you cannot conclude that a certificate is revoked
for good in this case, you would try to retrieve an update CRL to see if
the certificate on hold is still on it or not.