Add endpoint to get server publishing keys
This commit is contained in:
parent
38af22fea6
commit
ef9ae82e75
5 changed files with 58 additions and 13 deletions
|
@ -42,10 +42,7 @@ defmodule MatrixServer.Device do
|
||||||
|
|
||||||
def generate_device_id(localpart) do
|
def generate_device_id(localpart) do
|
||||||
# TODO: use random string instead
|
# TODO: use random string instead
|
||||||
time_string =
|
time_string = System.os_time(:millisecond) |> Integer.to_string()
|
||||||
DateTime.utc_now()
|
|
||||||
|> DateTime.to_unix()
|
|
||||||
|> Integer.to_string()
|
|
||||||
|
|
||||||
"#{localpart}_#{time_string}"
|
"#{localpart}_#{time_string}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,7 +28,7 @@ defmodule MatrixServer.Event do
|
||||||
room_id: room_id,
|
room_id: room_id,
|
||||||
sender: MatrixServer.get_mxid(localpart),
|
sender: MatrixServer.get_mxid(localpart),
|
||||||
event_id: generate_event_id(),
|
event_id: generate_event_id(),
|
||||||
origin_server_ts: DateTime.utc_now() |> DateTime.to_unix(),
|
origin_server_ts: System.os_time(:millisecond),
|
||||||
prev_events: [],
|
prev_events: [],
|
||||||
auth_events: []
|
auth_events: []
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ defmodule MatrixServer.Event do
|
||||||
event
|
event
|
||||||
|> Map.put(:hashes, %{"sha256" => content_hash})
|
|> Map.put(:hashes, %{"sha256" => content_hash})
|
||||||
|> redact()
|
|> redact()
|
||||||
|> SigningServer.sign_event()
|
|> SigningServer.sign_object()
|
||||||
end
|
end
|
||||||
|
|
||||||
defp calculate_content_hash(event) do
|
defp calculate_content_hash(event) do
|
||||||
|
|
|
@ -12,8 +12,12 @@ defmodule MatrixServer.SigningServer do
|
||||||
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
||||||
end
|
end
|
||||||
|
|
||||||
def sign_event(event) do
|
def sign_object(object) do
|
||||||
GenServer.call(__MODULE__, {:sign_event, event})
|
GenServer.call(__MODULE__, {:sign_object, object})
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_signing_keys do
|
||||||
|
GenServer.call(__MODULE__, :get_signing_keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
@ -27,12 +31,12 @@ defmodule MatrixServer.SigningServer do
|
||||||
# https://blog.swwomm.com/2020/09/elixir-ed25519-signatures-with-enacl.html
|
# https://blog.swwomm.com/2020/09/elixir-ed25519-signatures-with-enacl.html
|
||||||
@impl true
|
@impl true
|
||||||
def handle_call(
|
def handle_call(
|
||||||
{:sign_event, event},
|
{:sign_object, object},
|
||||||
_from,
|
_from,
|
||||||
%{private_key: private_key} = state
|
%{private_key: private_key} = state
|
||||||
) do
|
) do
|
||||||
ordered_map =
|
ordered_map =
|
||||||
event
|
object
|
||||||
|> Map.drop([:signatures, :unsigned])
|
|> Map.drop([:signatures, :unsigned])
|
||||||
|> OrderedMap.from_map()
|
|> OrderedMap.from_map()
|
||||||
|
|
||||||
|
@ -46,18 +50,24 @@ defmodule MatrixServer.SigningServer do
|
||||||
signature_map = %{@signing_key_id => signature}
|
signature_map = %{@signing_key_id => signature}
|
||||||
servername = MatrixServer.server_name()
|
servername = MatrixServer.server_name()
|
||||||
|
|
||||||
event =
|
signed_object =
|
||||||
Map.update(event, :signatures, %{servername => signature_map}, fn signatures ->
|
Map.update(object, :signatures, %{servername => signature_map}, fn signatures ->
|
||||||
Map.put(signatures, servername, signature_map)
|
Map.put(signatures, servername, signature_map)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{:reply, event, state}
|
{:reply, {:ok, signed_object}, state}
|
||||||
|
|
||||||
{:error, _msg} ->
|
{:error, _msg} ->
|
||||||
{:reply, {:error, :json_encode}, state}
|
{:reply, {:error, :json_encode}, state}
|
||||||
end
|
end
|
||||||
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...
|
# TODO: not sure if there is a better way to do this...
|
||||||
defp get_keys do
|
defp get_keys do
|
||||||
raw_priv_key =
|
raw_priv_key =
|
||||||
|
|
34
lib/matrix_server_web/controllers/key_controller.ex
Normal file
34
lib/matrix_server_web/controllers/key_controller.ex
Normal 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
|
|
@ -22,6 +22,10 @@ defmodule MatrixServerWeb.Router do
|
||||||
post "/login", AuthController, :login
|
post "/login", AuthController, :login
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope "/key/v2" do
|
||||||
|
get "/server", KeyController, :get_signing_keys
|
||||||
|
end
|
||||||
|
|
||||||
get "/client/versions", InfoController, :versions
|
get "/client/versions", InfoController, :versions
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue