I have my own HTTPS service that I am talking to from another Ruby app. I would like to save it's public key certificate at a known point in time in my app repo, and compare the public key that the service sends me with the stored copy. To install the certificate on the external server I'm likely to have to convert it to some format, so the file sent by the server is not going to be the same.
I want to do cert pinning of sorts, to that specific public key. What are the fields of the cert I need to compare using OpenSSL to verify that the PK I received from the service is the same as the one that's received from the server?
I imagine the CN and the signature have to match at least. What else needs to be checked to know that the public cert I have matches the one I've received exactly (i.e. is the same cert)? Maybe OSSL has a built-in facility for this?
As a follow-up to @Julik's answer, RestClient (https://github.com/rest-client/rest-client) supports
verify_callback
since 1.6.8.Ok, after a bit of poking at OpenSSL I've arrived at the following simple implementation of public key pinning. It's actually very simple. Unfortunately I don't see popular HTTP middleware libraries (like Faraday and HTTPClient) giving access to the
verify_callback
which is actually available on every OpenSSL session.In this example, the session will be terminated immediately if the PK doesn't match the one you have pinned previously. Note that the block will not be called with
OpenSSL::SSL::VERIFY_NONE
(which should never never never ever be used anyway).If you want to do whole certificate pinning and certs are not subject to rotation, you can use cert fingerprints:
EDIT: looks like at least excon implemented this recently:
https://github.com/geemus/excon/commit/12437b79bad2a0e51bb4ac5b79c155eb88128245