Commit a9c23e1c authored by lain's avatar lain

Add plug to validate signed http requests.

parent e2e63650
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
......@@ -376,4 +376,14 @@ def delete (%User{} = user) do
: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"}
......@@ -18,7 +20,18 @@ def split_signature(sig) do
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment