--- /dev/null
+defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
+ alias Pleroma.Web.HTTPSignatures
+ import Plug.Conn
+
+ def init(options) do
+ options
+ end
+
+ def call(conn, opts) do
+ if get_req_header(conn, "signature") do
+ conn = conn
+ |> put_req_header("(request-target)", String.downcase("#{conn.method} #{conn.request_path}"))
+
+ assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
+ else
+ conn
+ end
+ end
+end
:ok
end
+
+ def get_public_key_for_ap_id(ap_id) do
+ with %User{} = user <- get_cached_by_ap_id(ap_id),
+ %{info: %{"magic_key" => magic_key}} <- user,
+ public_key <- Pleroma.Web.Salmon.decode_key(magic_key) do
+ {:ok, public_key}
+ else
+ _ -> :error
+ end
+ end
end
# https://tools.ietf.org/html/draft-cavage-http-signatures-08
defmodule Pleroma.Web.HTTPSignatures do
+ alias Pleroma.User
+
def split_signature(sig) do
default = %{"headers" => "date"}
def validate(headers, signature, public_key) do
sigstring = build_signing_string(headers, signature["headers"])
{:ok, sig} = Base.decode64(signature["signature"])
- verify = :public_key.verify(sigstring, :sha256, sig, public_key)
+ :public_key.verify(sigstring, :sha256, sig, public_key)
+ end
+
+ def validate_conn(conn) do
+ # TODO: How to get the right key and see if it is actually valid for that request.
+ # For now, fetch the key for the actor.
+ with actor_id <- conn.params["actor"],
+ {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do
+ validate_conn(conn, public_key)
+ else
+ _ -> false
+ end
end
def validate_conn(conn, public_key) do