Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85827773
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/http_signatures/http_signatures.ex b/lib/http_signatures/http_signatures.ex
index 25bc9f1..018ee2e 100644
--- a/lib/http_signatures/http_signatures.ex
+++ b/lib/http_signatures/http_signatures.ex
@@ -1,81 +1,85 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: LGPL-3.0-only
# https://tools.ietf.org/html/draft-cavage-http-signatures-08
defmodule HTTPSignatures do
+ @moduledoc """
+ HTTP Signatures library.
+ """
+
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
adapter = Application.get_env(:http_signatures, :adapter)
with {:ok, public_key} <- adapter.fetch_public_key(conn) do
if validate_conn(conn, public_key) do
true
else
Logger.debug("Could not validate, trying to refetch any relevant keys")
with {:ok, public_key} <- adapter.refetch_public_key(conn) do
validate_conn(conn, public_key)
end
end
else
e ->
Logger.debug("Could not validate against known public keys: #{inspect(e)}")
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(private_key, key_id, headers) do
sigstring = build_signing_string(headers, Map.keys(headers))
signature =
:public_key.sign(sigstring, :sha256, private_key)
|> Base.encode64()
[
keyId: key_id,
algorithm: "rsa-sha256",
headers: Map.keys(headers) |> Enum.join(" "),
signature: signature
]
|> Enum.map(fn {k, v} -> "#{k}=\"#{v}\"" end)
|> Enum.join(",")
end
end
diff --git a/test/support/test_adapter.ex b/test/support/test_adapter.ex
index 01e173f..58b9b4b 100644
--- a/test/support/test_adapter.ex
+++ b/test/support/test_adapter.ex
@@ -1,34 +1,36 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: LGPL-3.0-only
defmodule HTTPSignatures.TestAdapter do
@behaviour HTTPSignatures.Adapter
+ @moduledoc "Test adapter for HTTPSignatures library."
+
@mastodon_admin_pubkey hd(
:public_key.pem_decode(
File.read!("test/admin@mastodon.example.org.key")
)
)
|> :public_key.pem_entry_decode()
@rye_pubkey hd(:public_key.pem_decode(File.read!("test/rye@niu.moe.key")))
|> :public_key.pem_entry_decode()
@lm_pubkey hd(
:public_key.pem_decode(File.read!("test/lucifermysticus@mst3k.interlinked.me.key"))
)
|> :public_key.pem_entry_decode()
def fetch_public_key(_), do: {:ok, @mastodon_admin_pubkey}
def refetch_public_key(%{params: %{"actor" => "https://niu.moe/users/rye"}}),
do: {:ok, @rye_pubkey}
def refetch_public_key(%{
params: %{"actor" => "https://mst3k.interlinked.me/users/luciferMysticus"}
}),
do: {:ok, @lm_pubkey}
def refetch_public_key(_), do: {:error, "no public key found"}
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Oct 30, 11:07 PM (16 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1800705
Default Alt Text
(4 KB)
Attached To
Mode
R18 http_signatures
Attached
Detach File
Event Timeline