diff options
author | lambda <lain@soykaf.club> | 2019-05-15 15:37:31 +0000 |
---|---|---|
committer | lambda <lain@soykaf.club> | 2019-05-15 15:37:31 +0000 |
commit | 4440e23547dddc58252318282e3f417bafd6ee4c (patch) | |
tree | bcc003b66b71c9edb587be7879e0a6cd899b3e7d /lib | |
parent | 18f2d2024daa682cdb02c57eeb4c08d377a9a0a9 (diff) | |
parent | 4429c1b7dae9007299c46eab8bd60573b9ff1bdb (diff) | |
download | pleroma-4440e23547dddc58252318282e3f417bafd6ee4c.tar.gz |
Merge branch 'chore/extricate-http-signatures' into 'develop'
switch to pleroma/http_signatures library
See merge request pleroma/pleroma!1155
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/plugs/http_signature.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/signature.ex | 41 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/publisher.ex | 2 | ||||
-rw-r--r-- | lib/pleroma/web/http_signatures/http_signatures.ex | 91 |
4 files changed, 42 insertions, 93 deletions
diff --git a/lib/pleroma/plugs/http_signature.ex b/lib/pleroma/plugs/http_signature.ex index 21c195713..e2874c469 100644 --- a/lib/pleroma/plugs/http_signature.ex +++ b/lib/pleroma/plugs/http_signature.ex @@ -4,7 +4,6 @@ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do alias Pleroma.Web.ActivityPub.Utils - alias Pleroma.Web.HTTPSignatures import Plug.Conn require Logger diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex new file mode 100644 index 000000000..b7ecf00a0 --- /dev/null +++ b/lib/pleroma/signature.ex @@ -0,0 +1,41 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Signature do + @behaviour HTTPSignatures.Adapter + + alias Pleroma.User + alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.Salmon + alias Pleroma.Web.WebFinger + + def fetch_public_key(conn) do + with actor_id <- Utils.get_ap_id(conn.params["actor"]), + {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do + {:ok, public_key} + else + e -> + {:error, e} + end + end + + def refetch_public_key(conn) do + with actor_id <- Utils.get_ap_id(conn.params["actor"]), + {:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id), + {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do + {:ok, public_key} + else + e -> + {:error, e} + end + end + + def sign(%User{} = user, headers) do + with {:ok, %{info: %{keys: keys}}} <- WebFinger.ensure_keys_present(user), + {:ok, private_key, _} <- Salmon.keys_from_pem(keys) do + HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers) + end + end +end diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex index 8e3af0a81..11dba87de 100644 --- a/lib/pleroma/web/activity_pub/publisher.ex +++ b/lib/pleroma/web/activity_pub/publisher.ex @@ -54,7 +54,7 @@ defmodule Pleroma.Web.ActivityPub.Publisher do |> Timex.format!("{WDshort}, {0D} {Mshort} {YYYY} {h24}:{m}:{s} GMT") signature = - Pleroma.Web.HTTPSignatures.sign(actor, %{ + Pleroma.Signature.sign(actor, %{ host: host, "content-length": byte_size(json), digest: digest, diff --git a/lib/pleroma/web/http_signatures/http_signatures.ex b/lib/pleroma/web/http_signatures/http_signatures.ex deleted file mode 100644 index 8e2e2a44b..000000000 --- a/lib/pleroma/web/http_signatures/http_signatures.ex +++ /dev/null @@ -1,91 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> -# SPDX-License-Identifier: AGPL-3.0-only - -# https://tools.ietf.org/html/draft-cavage-http-signatures-08 -defmodule Pleroma.Web.HTTPSignatures do - alias Pleroma.User - alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.ActivityPub.Utils - - require Logger - - def split_signature(sig) do - default = %{"headers" => "date"} - - sig = - sig - |> String.trim() - |> String.split(",") - |> Enum.reduce(default, fn part, acc -> - [key | rest] = String.split(part, "=") - value = Enum.join(rest, "=") - Map.put(acc, key, String.trim(value, "\"")) - end) - - Map.put(sig, "headers", String.split(sig["headers"], ~r/\s/)) - end - - def validate(headers, signature, public_key) do - sigstring = build_signing_string(headers, signature["headers"]) - Logger.debug("Signature: #{signature["signature"]}") - Logger.debug("Sigstring: #{sigstring}") - {:ok, sig} = Base.decode64(signature["signature"]) - :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 <- Utils.get_ap_id(conn.params["actor"]), - {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do - if validate_conn(conn, public_key) do - true - else - Logger.debug("Could not validate, re-fetching user and trying one more time") - # Fetch user anew and try one more time - with actor_id <- Utils.get_ap_id(conn.params["actor"]), - {:ok, _user} <- ActivityPub.make_user_from_ap_id(actor_id), - {:ok, public_key} <- User.get_public_key_for_ap_id(actor_id) do - validate_conn(conn, public_key) - end - end - else - _e -> - Logger.debug("Could not public key!") - false - end - end - - def validate_conn(conn, public_key) do - headers = Enum.into(conn.req_headers, %{}) - signature = split_signature(headers["signature"]) - validate(headers, signature, public_key) - end - - def build_signing_string(headers, used_headers) do - used_headers - |> Enum.map(fn header -> "#{header}: #{headers[header]}" end) - |> Enum.join("\n") - end - - def sign(user, headers) do - with {:ok, %{info: %{keys: keys}}} <- Pleroma.Web.WebFinger.ensure_keys_present(user), - {:ok, private_key, _} = Pleroma.Web.Salmon.keys_from_pem(keys) do - sigstring = build_signing_string(headers, Map.keys(headers)) - - signature = - :public_key.sign(sigstring, :sha256, private_key) - |> Base.encode64() - - [ - keyId: user.ap_id <> "#main-key", - algorithm: "rsa-sha256", - headers: Map.keys(headers) |> Enum.join(" "), - signature: signature - ] - |> Enum.map(fn {k, v} -> "#{k}=\"#{v}\"" end) - |> Enum.join(",") - end - end -end |