Earlier this evening I proposed a patch that adds support for
requiring/verifying TLS client certificates to httpd. See my last post.

But that only solves half the problem (checking that the client cert
was issued by a locally-trusted CA and has not yet expired).

The other (and in my opinion equally important) half is checking that
the client cert has not yet been revoked (without that check, there
seems little point verifying certificate authenticity). There are a
bunch of different ways of going about that.

Assuming that the devs are happy to go down the path of supporting TLS
client certs in httpd (if not, the rest of this post will be pointless,
so just ignore it), I'm looking for some feedback on the most
*desirable* approach to client cert revocation status checking.

My own thoughts (for what they're worth) are:

OCSP stapling, whilst ideal (and already supported) for server certs,
is unlikely to be of much practical use with client certs (since, at
least from my experience, users -- especially non-technical users --
are likely to see the burden on them as too great to justify).

Online OSCP (or worse, online CRL checking) tends to be discouraged,
due to the amount of extra per-request traffic generated. In both cases,
that would involve adding an http client to httpd, which really doesn't
seem like a sensible place to implement such a thing... (complexity,
monoliths, etc. etc.)

But with client certs (as opposed to server certs), it's much more
common for the issuing entity & the verifying entity to be one & the
same. So local methods are probably worth exploring. As far as I can
tell, there are three potentially viable alternatives:

Noting that RFC6960 does not require using HTTP as the transport for
OCSP, talking to a local OSCP responder over a Unix socket (much as
httpd already does with fastcgi responders) might be a possibility.
libtls already provides tls_ocsp_process_response(), so all httpd would
need to do is craft the query, send it to the socket & pass back the
response. That seems to limit complexity in httpd nicely, but creates a
need to write a new OCSP repsonder...

Checking a local CRL file (the approach taken by apache & nginx) would
also be relatively easy to implement, although it would require at least
a minor patch to libtls first, to expose the cert serial number & CRL
URL (or alternatively, just have libtls wrap libssl's local CRL checking
routines?). Even if the issuing & verifying parties are not the same,
this could still work reasonably well -- e.g. with a simple cron job
refreshing a local cached copy of the CRL (still need to fetch the
whole CRL whenever it changes, but that's a lot better than fetching
anything on a per-request basis). Only drawback is that there's a lot
of talk about CRLs being deprecated...

Alternatively, noting that client certs are most often used with
dynamic sites, client cert revocation status checking could perhaps be
left to the fastcgi responder. We're already (if the diff proposed in my
other post gets accepted) passing through TLS_PEER_OCSP_URL &
TLS_PEER_HASH. With a small patch to libtls it would trivial to have
httpd pass through the client cert's CRL URL & serial number too (both
methods require the cert serial number). That would provide the most
flexibility (fastcgi responders could choose to use OSCP, CRLs or
something else; online or against local files) and keep both httpd &
libtls as simple as possible, but does add a bit of work for those
implementing fastcgi responders (although that could be done once as a
separate library, perhaps in ports).

Without modifying libtls, the only way I can see to have a fastcgi
responder do client cert revocation status checking would be to
implement a bespoke protocol for checking a non-standard CRL substitute
file (presumably keyed by TLS_PEER_HASH), which is something I'd really
prefer to avoid given that the problem is obviously of such generic
applicability.

Personally, I'm leaning towards either local CRL file checking in
httpd (with minimal changes to libtls), or passing through enough data
to the let the fastcgi responders take whichever approach they want.

I'm interested in thoughts from the devs -- am I on the right track or
have I missed something obvious? If httpd is to gain support for TLS
client certificate verification (including revocation status checking),
which approach would fit in best with the OpenBSD design philosophy?
Does the bulk of the code "belong" in libtls or in httpd or should as
much as possible be left to the fastcgi responders?

Thanks.

Reply via email to