Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
proposal: crypto/x509: implement OCSP verifier #40017
Although we have a golang.org/x/crypto/ocsp package, we don't in fact have an OCSP verifier. The existing package provides serialization and parsing, but not APIs for "get me an OCSP response for this certificate" and "given this certificate and this OCSP response tell me if it's revoked". (They are separate because you only want the latter when checking stapled responses.)
There is a lot of complexity, subtlety, and dark knowledge involved in OCSP unfortunately. Here are a few notes on things the verifier needs to do (from reading this thread):
There are definitely a lot more things to consider (for example, the
A difficult question is where to put the code, and how to surface it. We'll want to use it in crypto/tls for Must-Staple (#22274) but it feels like the wrong place for the code to live. An obvious answer would be golang.org/x/crypto/ocsp, but then we can't use it from crypto/x509 without an import loop. Should
We should also look around the ecosystem, because surely someone had to implement this, and we should compare results.
I think this would go a long way towards getting rid of the numerous traps
For delegated responders it probably makes sense to ignore whether a delegated responder contains
Fetching code probably should live in
There is a bit of a chicken and egg problem with the fetching code and the verification code. For generating the OCSP request you need the leaf issuer, which means you might want to do chain building before you request the OCSP response (otherwise you need to do some pre-processing to determine the issuer, or you just assume the second cert in any chain you were sent is the issuer...), but as previously mentioned it'd probably be nicer to be able to do OCSP verification during chain building. The other less desirable option would be to to add a new
I vote to implement this in
We might also want to cache the response according to the
Right, as Roland suggests, doing it during chain building is the 'desired' implementation.
RFC 4158, Section 3.5.9 discusses some of the trade-offs here. Note that, depending on how you want to handle
That is, if you have
It's possible for Server to be responded by Responder 1, who when you check status (i.e. it lacks
It feels like there are two different paths we can go down here, implementing verification with out-of-band fetching (i.e. verifying using a stapled, or otherwise fetched, response) or verification with in-band fetching (i.e. fetching responses during verification) These can share a good bit of code (basically the actual verification logic) but have different implementation complexities.
It seems like probably the path with the least friction, for now anyway, is implementation out-of-band verification first and then deciding on the more complex problem of adding in-band verification once that is complete.
Fetching OCSP can introduce both privacy and usability surprises. Privacy: Your client is now talking to somebody unexpected (based on an HTTP URL in the AIA OCSP item) and it's telling them which certificate you're currently interested in. It is obliged to use plaintext HTTP for this transaction and although the answers should be signed (so a MITM can't fake the response) the query can be read by anybody on the path.
Usability: Sometimes (too often) OCSP servers aren't reachable. Sometimes this is because they are on the Internet and you can't reach some or all of the public Internet from where you are. Sometimes though it's just the OCSP server is down.
In contrast the Stapled scenario is pretty much worry free.
As a result I'd strongly urge that any opt-in / opt-out type behaviour focuses on these network behaviours (whether to fetch stuff, over HTTP, from some server we discovered in the AIA records) not on disabling / enabling OCSP checking itself.
In particular it's desirable that on the one hand a quiet piece of software doesn't end up broadcasting its existence to the world because it saw some random Let's Encrypt certificate, while on the other hand a certificate with OCSP-must-staple set is always rejected by a Go program if that OCSP response is missing.
Yes, however we end up structuring the API, a verification by default will not contact the network.
I'd still like to put fetching in a separate package, but it sounds like it would require a chain, and the chain comes from Verify, but the response would be fed to Verify.