Packages

A test Acme server for generating SSL Certificates

Current section

Files

Jump to
acme_ex lib jws.ex
Raw

lib/jws.ex

defmodule AcmeEx.Jws do
def client_key(request), do: Map.fetch!(request.protected, "jwk")
def decode(""), do: {:error, :empty}
def decode(body) when is_binary(body) do
body |> decode_json!() |> decode()
end
def decode(data) do
case verify(data) do
{:ok, payload} ->
{:ok, %{payload: payload, protected: data |> unwrap("protected")}}
error ->
error
end
end
def thumbprint(request), do: JOSE.JWK.thumbprint(request)
def unwrap(body) do
body
|> decode_json!()
|> Enum.map(fn {k, v} ->
case k do
"signature" -> {k, v}
_ -> {k, v |> decode64_json!()}
end
end)
|> Map.new()
end
def unwrap(body, field), do: body |> unwrap() |> Map.get(field)
def format(body) do
body
|> decode_json!()
|> (&%{
"payload" => Map.fetch!(&1, "payload"),
"signatures" => [
%{
"protected" => Map.fetch!(&1, "protected"),
"signature" => Map.fetch!(&1, "signature")
}
]
}).()
end
def key(body) do
body
|> unwrap()
|> (&get_in(&1, ["protected", "jwk"])).()
|> JOSE.JWK.from()
end
defp verify(body) do
body
|> decode_json!()
|> (&(case JOSE.JWS.verify([key(&1)], format(&1)) do
[{_jwk, [{true, payload, _jws}]}] ->
{:ok, payload |> decode_json!}
{:error, reason} ->
{:error, "Unable to verify data due to #{reason |> Kernel.inspect()}"}
end)).()
end
defp decode_json!(body) when is_binary(body), do: Jason.decode!(body)
defp decode_json!(data), do: data
defp decode64_json!(v) do
v
|> Base.decode64!(padding: false)
|> Jason.decode!()
end
end