encrypted ids work

This commit is contained in:
Moon Man 2024-08-25 22:05:24 +00:00
parent 700f64df1c
commit a434c693d5
5 changed files with 82 additions and 1 deletions

View File

@ -1,2 +1,5 @@
# vonbraun
Run:
elixir --erl '-args_file vm.args' -S mix run --no-halt

View File

@ -12,4 +12,6 @@ config :vonbraun,
nickname: "moonman",
domain: "vonbraun.discontent.top",
summary: "I am the famous Fediverse Moon",
approve_followers: false
approve_followers: false,
# MUST be 32
id_key: "53F0CB234DA3DB1A43AE32DE4038516B"

11
lib/vonbraun/control.ex Normal file
View File

@ -0,0 +1,11 @@
defmodule Vonbraun.Control do
def follow(id) when is_binary(id) do
end
def unfollow(id) when is_binary(id) do
end
def post_note(content, public?, to \\ [])
when is_binary(content) and is_list(to) and is_boolean(public?) do
end
end

63
lib/vonbraun/crypto_id.ex Normal file
View File

@ -0,0 +1,63 @@
defmodule Vonbraun.CryptoID do
require Logger
@spec encrypt(integer()) :: String.t()
@spec encrypt(integer(), <<_::128>>) :: String.t()
def encrypt(epoch_milliseconds, <<iv::bytes-size(16)>> \\ :crypto.strong_rand_bytes(16))
when is_integer(epoch_milliseconds) do
key = Application.fetch_env!(:vonbraun, :id_key) |> Base.decode16!()
encrypted =
:crypto.crypto_one_time(:aes_128_ctr, key, iv, <<epoch_milliseconds::64-big>>, true)
Logger.debug("bytes length of encrypted: #{byte_size(encrypted)}")
Base.encode16(iv <> encrypted)
end
def to_milliseconds(<<iv_hex::bytes-size(32), encrypted_payload::bytes-size(16)>>) do
key = Application.fetch_env!(:vonbraun, :id_key) |> Base.decode16!()
with {:iv_decode, {:ok, iv}} <- {:iv_decode, Base.decode16(iv_hex)},
{:decode, {:ok, encrypted_bytes}} <- {:decode, Base.decode16(encrypted_payload)},
{:decrypt, <<epoch_milliseconds::64>>} <-
{:decrypt, :crypto.crypto_one_time(:aes_128_ctr, key, iv, encrypted_bytes, false)} do
{:ok, epoch_milliseconds}
else
{:iv_decode, :error} ->
{:error, :iv_decode}
{:decode, :error} ->
{:error, :base16_decode}
{:decrypt, _} ->
{:error, :integer_decrypt}
end
end
def encrypt_id(epoch_milliseconds) when is_integer(epoch_milliseconds) do
encrypted_milliseconds = encrypt(epoch_milliseconds)
instance = Application.fetch_env!(:vonbraun, :domain)
"https://#{instance}/id/#{encrypted_milliseconds}"
end
def now!() do
epoch_milliseconds = System.system_time(:microsecond)
id = encrypt_id(epoch_milliseconds)
{id, epoch_milliseconds}
end
def decrypt_id(id) when is_binary(id) do
instance = Application.fetch_env!(:vonbraun, :domain)
prefix = "https://#{instance}/id/"
with {:prefix, ^prefix <> <<payload::bytes-size(48)>>} <- {:prefix, id},
{:ms, {:ok, milliseconds}} <- {:ms, to_milliseconds(payload)} do
{:ok, milliseconds}
else
{:prefix, _} -> {:error, :prefix_unmatch}
{:ms, {:error, error}} -> {:error, error}
end
end
end

2
vm.args Normal file
View File

@ -0,0 +1,2 @@
-name vb@falco
-setcookie cookie