snoyberg/http-conduit — Issue #7: Cache of valid certificates
Author: meteficha
Created: 2012-01-17 19:28:37+00:00
State: open

Hey!

It's very nice that now we check every certificate. However, that means that we need to check *every* certificate against the system list of certificates. This means not only a lot of file I/O, but also a lot of CPU usage while checking signatures.

So I think that it makes sense to create a cache of valid certificates. Pros: less CPU usage, less I/O. Cons: more memory usage (but I don't that it would be significant in practice).

Some nice-to-have properties of this cache:

1. Each certificate needs a timeout. First of all, a timeout is needed because certificates could expire while our `Manager` is being used. But also, if the user ever removes a CA from the system cache, it would be nice for any certificates signed by that CA to expire sometime before 2015.

2. The cache is per `Manager`, per `ConnKey`. Having a cache on the `ConnKey` means that we don't need to check the domain of the certificate again (if it matches a certificate on the cache). That also means that after all keep-alive connections get reaped, their cached certificates get freed too and we don't need to worry about reaping certificates. And, finally, a malicious host can't fill our caches (since we can have a limit of how many certificates we cache per key) and force cache misses (since only their own certificates get flushed out of the cache) by sending a new, valid certificate on each request (althought that sounds like crazy).

Note that I don't know if it's a good idea or not to cache invalid certificates as well. I'm leaning towards "no" at least for now. The bad thing about not caching them is that they're the worst-case scenario when looking for a corresponding system CA. OTOH, assuming that someone somehow wanted to do cause a DoS by giving us invalid certificates, these certificates may be so easy to create that they'll be able to always send a new, unique certificate, defeating the cache.

What do you think? =)