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
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
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
|
||||
end
|
||||
|
||||
scope "/key/v2" do
|
||||
get "/server", KeyController, :get_signing_keys
|
||||
end
|
||||
|
||||
get "/client/versions", InfoController, :versions
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue