Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F140752
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
3 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 3e666b5..c486727 100644
--- a/lib/http_signatures/http_signatures.ex
+++ b/lib/http_signatures/http_signatures.ex
@@ -1,91 +1,96 @@
# 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
@doc "Get signature for conn in split form."
def signature_for_conn(conn) do
- headers = Enum.into(conn.req_headers, %{})
- split_signature(headers["signature"])
+ with headers <- Enum.into(conn.req_headers, %{}),
+ signature when is_binary(signature) <- headers["signature"] do
+ split_signature(signature)
+ else
+ _ ->
+ %{}
+ end
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
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jan 21, 9:47 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55702
Default Alt Text
(3 KB)
Attached To
Mode
R18 http_signatures
Attached
Detach File
Event Timeline
Log In to Comment