Detecting SSL details/expiry for an arbitrary URL?

Most HTTP clients do not expose the SSL socket to the caller, and to inspect the server’s certificate you don’t need to send an HTTP request at all, so I would recommend you just go with :ssl directly.

For example, using x509 to inspect the certificate:

with {:ok, sock} <- :ssl.connect(to_charlist(hostname), 443, []),
     {:ok, cert_der} <- :ssl.peercert(sock),
     :ssl.close(sock),
     {:ok, cert} <- X509.Certificate.from_der(cert_der),
     {:Validity, _not_before, not_after} <- X509.Certificate.validity(cert) do
  X509.DateTime.to_datetime(not_after)
end

Note that this does not enable certificate verification, so in theory someone could launch a MitM attack and present a spoofed certificate. Not sure that’s a real concern here (it should be if you were to use the SSL connection for anything non-trivial), but you may want to add additional ssl options to address that…

(I just remember I proposed almost exactly that snippet before: Get SSL expiry date from an http request using Mint / Finch / Mojito)

5 Likes