Add endpoint to get server publishing keys

This commit is contained in:
Pim Kunis 2021-08-06 15:52:03 +02:00
parent 38af22fea6
commit ef9ae82e75
5 changed files with 58 additions and 13 deletions

View file

@ -42,10 +42,7 @@ defmodule MatrixServer.Device do
def generate_device_id(localpart) do
# TODO: use random string instead
time_string =
DateTime.utc_now()
|> DateTime.to_unix()
|> Integer.to_string()
time_string = System.os_time(:millisecond) |> Integer.to_string()
"#{localpart}_#{time_string}"
end

View file

@ -28,7 +28,7 @@ defmodule MatrixServer.Event do
room_id: room_id,
sender: MatrixServer.get_mxid(localpart),
event_id: generate_event_id(),
origin_server_ts: DateTime.utc_now() |> DateTime.to_unix(),
origin_server_ts: System.os_time(:millisecond),
prev_events: [],
auth_events: []
}
@ -281,7 +281,7 @@ defmodule MatrixServer.Event do
event
|> Map.put(:hashes, %{"sha256" => content_hash})
|> redact()
|> SigningServer.sign_event()
|> SigningServer.sign_object()
end
defp calculate_content_hash(event) do

View file

@ -12,8 +12,12 @@ defmodule MatrixServer.SigningServer do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def sign_event(event) do
GenServer.call(__MODULE__, {:sign_event, event})
def sign_object(object) do
GenServer.call(__MODULE__, {:sign_object, object})
end
def get_signing_keys do
GenServer.call(__MODULE__, :get_signing_keys)
end
## Implementation
@ -27,12 +31,12 @@ defmodule MatrixServer.SigningServer do
# https://blog.swwomm.com/2020/09/elixir-ed25519-signatures-with-enacl.html
@impl true
def handle_call(
{:sign_event, event},
{:sign_object, object},
_from,
%{private_key: private_key} = state
) do
ordered_map =
event
object
|> Map.drop([:signatures, :unsigned])
|> OrderedMap.from_map()
@ -46,18 +50,24 @@ defmodule MatrixServer.SigningServer do
signature_map = %{@signing_key_id => signature}
servername = MatrixServer.server_name()
event =
Map.update(event, :signatures, %{servername => signature_map}, fn signatures ->
signed_object =
Map.update(object, :signatures, %{servername => signature_map}, fn signatures ->
Map.put(signatures, servername, signature_map)
end)
{:reply, event, state}
{:reply, {:ok, signed_object}, state}
{:error, _msg} ->
{:reply, {:error, :json_encode}, state}
end
end
def handle_call(:get_signing_keys, _from, %{public_key: public_key} = state) do
encoded_public_key = MatrixServer.encode_unpadded_base64(public_key)
{:reply, [{@signing_key_id, encoded_public_key}], state}
end
# TODO: not sure if there is a better way to do this...
defp get_keys do
raw_priv_key =

View file

@ -0,0 +1,34 @@
defmodule MatrixServerWeb.KeyController do
use MatrixServerWeb, :controller
import MatrixServerWeb.Plug.Error
alias MatrixServer.SigningServer
@key_valid_time_ms 1000 * 60 * 24 * 30
def get_signing_keys(conn, _params) do
keys =
SigningServer.get_signing_keys()
|> Enum.into(%{}, fn {key_id, key} ->
{key_id, %{"key" => key}}
end)
data = %{
server_name: MatrixServer.server_name(),
verify_keys: keys,
old_verify_keys: %{},
valid_until_ts: System.os_time(:millisecond) + @key_valid_time_ms
}
case SigningServer.sign_object(data) do
{:ok, signed_data} ->
conn
|> put_status(200)
|> json(signed_data)
{:error, _msg} ->
put_error(conn, :unknown, "Error signing object.")
end
end
end

View file

@ -22,6 +22,10 @@ defmodule MatrixServerWeb.Router do
post "/login", AuthController, :login
end
scope "/key/v2" do
get "/server", KeyController, :get_signing_keys
end
get "/client/versions", InfoController, :versions
end