Skip to content

Instantly share code, notes, and snippets.

@voltone
Created July 11, 2018 11:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save voltone/94a4e256b24a746b29de1185d9545ac5 to your computer and use it in GitHub Desktop.
Save voltone/94a4e256b24a746b29de1185d9545ac5 to your computer and use it in GitHub Desktop.
OCSP response cache
config :sample, SampleWeb.Endpoint,
https: [
port: 4001,
sni_fun: &SampleWeb.Endpoint.ssloptions/1,
keyfile: "priv/cert/privkey.pem",
certfile: "priv/cert/cert.pem",
cacertfile: "priv/cert/chain.pem",
dhfile: "priv/cert/dhparams.pem",
secure_renegotiate: true,
versions: [:"tlsv1.2"]
],
cache_static_manifest: "priv/static/cache_manifest.json"
# To create the OCSP request URL, create a binary request using OpenSSL
# as described here: http://unmitigatedrisk.com/?p=42
# Encode the result as base64 and URL-encode the result, then append
# it to server certificate's OCSP endpoint URL
config :sample, Sample.OCSPResponseCache,
request:
"http://ocsp.int-x3.letsencrypt.org/MFMwUTBPME0wSzAJBgUrDgMCGgUABBR%2B5mrncpqz%2FPiiIGRsFqEtYHEIXQQUqEpqYwR93brm0Tm3pkVl7%2FOo7KECEgSCMGvPKVhNmwWOxVUD3Ht%2Blg%3D%3D"
defmodule Sample.OCSPResponseCache do
use GenServer
require Logger
@renew_interval 3_600_000
@retry_interval 60_000
def start_link([]) do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end
def get() do
case :ets.lookup(__MODULE__, :response) do
[{:response, response}] ->
response
_ ->
nil
end
end
@impl GenServer
def init([]) do
config = Application.get_env(:sample, __MODULE__, [])
case Keyword.get(config, :request) do
nil ->
:ignore
request ->
:ets.new(__MODULE__, [:set, :protected, :named_table, read_concurrency: true])
{:ok, request, 0}
end
end
@impl GenServer
def handle_info(:timeout, request) do
renew(request)
end
defp renew(request) do
case :httpc.request(:get, {to_charlist(request), []}, [], body_format: :binary) do
{:ok, {_, _, resp}} ->
:ets.insert(__MODULE__, {:response, resp})
Logger.info("OCSP response renewed")
{:noreply, request, @renew_interval}
error ->
Logger.error("Failed to renew OCSP response:\n#{inspect(error)}")
{:noreply, request, @retry_interval}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment