From c48367ff09a926b66927daa39626d978ef0abf96 Mon Sep 17 00:00:00 2001 From: Alain Zscheile Date: Sat, 26 Nov 2022 23:41:53 +0100 Subject: [PATCH] send public key with every message this is more efficient and solves key distribution concerns --- asn1/FloofProtocol.asn1 | 4 +- lib/floof/application.ex | 6 +-- lib/floof/distributor.ex | 62 +++++++++++----------------- lib/floof/message.ex | 13 +++--- lib/floof/pubkey_mgr.ex | 24 ----------- mix.exs | 3 -- mock_keydb/AQoJkiaJk_IsZAEZBHRlc3Q= | 1 - test/floof_test.exs | 5 +-- {mock_keydb => test}/test01.secret | Bin 9 files changed, 34 insertions(+), 84 deletions(-) delete mode 100644 lib/floof/pubkey_mgr.ex delete mode 100644 mock_keydb/AQoJkiaJk_IsZAEZBHRlc3Q= rename {mock_keydb => test}/test01.secret (100%) diff --git a/asn1/FloofProtocol.asn1 b/asn1/FloofProtocol.asn1 index e760d33..01e1bf6 100644 --- a/asn1/FloofProtocol.asn1 +++ b/asn1/FloofProtocol.asn1 @@ -3,6 +3,7 @@ DEFINITIONS EXPLICIT TAGS ::= BEGIN Signature ::= SEQUENCE { algorithm OBJECT IDENTIFIER, + key OCTET STRING, value OCTET STRING } Severity ::= ENUMERATED { @@ -38,9 +39,6 @@ XferInner ::= SEQUENCE { } XferBlob ::= SEQUENCE { - -- source system name -- - source RDNSequence, - -- message max remaining hops ttl INTEGER (0..255), diff --git a/lib/floof/application.ex b/lib/floof/application.ex index 1bb00a3..378c8ad 100644 --- a/lib/floof/application.ex +++ b/lib/floof/application.ex @@ -14,8 +14,6 @@ defmodule Floof.Application do markers = Application.fetch_env!(:floof, :markers) attrs = Application.fetch_env!(:floof, :attrs) set_markers = Application.fetch_env!(:floof, :set_markers) - pubkey_mgr = Application.fetch_env!(:floof, :pubkey_mgr) - pubkey_config = Application.fetch_env!(:floof, :pubkey_config) spool_dir = Application.fetch_env!(:floof, :spool_dir) sessions_file = Application.fetch_env!(:floof, :sessions_file) @@ -30,9 +28,7 @@ defmodule Floof.Application do Floof.Distributor.fconfig( markers: markers, attrs: attrs, - set_markers: set_markers, - pubkey_mgr: pubkey_mgr, - pubkey_config: pubkey_config + set_markers: set_markers )}, {Floof.SessionManager, {:sessions, [file: to_charlist(sessions_file)]}} ] ++ diff --git a/lib/floof/distributor.ex b/lib/floof/distributor.ex index 82c0b53..bf9de86 100644 --- a/lib/floof/distributor.ex +++ b/lib/floof/distributor.ex @@ -12,9 +12,7 @@ defmodule Floof.Distributor do Record.defrecord(:fconfig, markers: [], attrs: [], - set_markers: [], - pubkey_mgr: Floof.Distributor.PubkeyMgr.FileDB, - pubkey_config: %{:keydb => ""} + set_markers: [] ) Record.defrecord(:dstate, fconf: {}, trgs: MapSet.new()) @@ -71,10 +69,10 @@ defmodule Floof.Distributor do # spawn a separate process to avoid blocking the queue # we only block the queue above for the check + seen marker spawn_link(fn -> - {:XferBlob, source, ttl, old_markers, signature, data} = dcd + {:XferBlob, ttl, old_markers, signature, data} = dcd set_markers = fconfig(fconf, :set_markers) new_markers = Enum.uniq(set_markers ++ old_markers) - dcd2 = {:XferBlob, source, ttl - 1, new_markers, signature, data} + dcd2 = {:XferBlob, ttl - 1, new_markers, signature, data} for trg <- trgs do send(trg, {:fwdxfer, {dcdhash, dcd2}}) @@ -93,40 +91,30 @@ defmodule Floof.Distributor do end defp check_incoming(fconf, dcdhash, dcd) do - {:XferBlob, source, ttl, _, {:Signature, sigalgo, sigval}, xfinner} = dcd + {:XferBlob, ttl, _, {:Signature, sigalgo, pubkey, sigval}, xfinner} = dcd case sigalgo do {1, 3, 6, 1, 4, 1, 11591, 15, 1} -> # Ed25519 - case get_pubkey(fconf, source) do - {:ok, :ed25519, pubkey} -> - cond do - Floof.DistributorSeen.have_we(dcdhash) -> - # we can ignore this packet, its content was already processed - false - - not :enacl.sign_verify_detached(sigval, xfinner, pubkey) -> - Logger.error("packet signature invalid for #{inspect(xfinner)}") - false - - ttl == 0 -> - Logger.warn("packet in processing expired (out of hops): #{inspect(xfinner)}") - false - - not check_filters(fconf, dcd) -> - Logger.debug("packet discarded according to filters: #{inspect(xfinner)}") - false - - true -> - true - end - - _ -> - Logger.warn( - "unable to verify packet signature due to unknown signer: #{inspect(source)}" - ) - + cond do + Floof.DistributorSeen.have_we(dcdhash) -> + # we can ignore this packet, its content was already processed false + + not :enacl.sign_verify_detached(sigval, xfinner, pubkey) -> + Logger.error("packet signature invalid for #{inspect(xfinner)}") + false + + ttl == 0 -> + Logger.warn("packet in processing expired (out of hops): #{inspect(xfinner)}") + false + + not check_filters(fconf, dcd) -> + Logger.debug("packet discarded according to filters: #{inspect(xfinner)}") + false + + true -> + true end _ -> @@ -138,7 +126,7 @@ defmodule Floof.Distributor do end end - defp check_filters(fconf, {:XferBlob, _, _, markers, _, xfinner}) do + defp check_filters(fconf, {:XferBlob, _, markers, _, xfinner}) do try do {:ok, {:XferInner, _, attrs, _, _}} = :FloofProtocol.decode(:XferInner, xfinner) @@ -171,8 +159,4 @@ defmodule Floof.Distributor do defp check_filters_markers2([], _) do true end - - defp get_pubkey(fconf, source) do - fconfig(fconf, :pubkey_mgr).get_pubkey(fconfig(fconf, :pubkey_config), source) - end end diff --git a/lib/floof/message.ex b/lib/floof/message.ex index 6c9ac00..77aab85 100644 --- a/lib/floof/message.ex +++ b/lib/floof/message.ex @@ -4,17 +4,18 @@ defmodule Floof.Message do """ def emit(xf) do - {:XferBlob, _, _, _, _, xfinner} = xf + {:XferBlob, _, _, _, xfinner} = xf mhash = :crypto.hash(:blake2b, xfinner) GenServer.cast(Floof.Distributor, {:xfer, {self(), mhash, xf}}) mhash end def sign(xf, secret_key) do - {:XferBlob, source, ttl, markers, _, xfinner} = xf + {:XferBlob, ttl, markers, _, xfinner} = xf + public_key = :enacl.crypto_sign_ed25519_sk_to_pk(secret_key) signature = :enacl.sign_detached(xfinner, secret_key) - signature2 = {:Signature, {1, 3, 6, 1, 4, 1, 11591, 15, 1}, signature} - {:XferBlob, source, ttl, markers, signature2, xfinner} + signature2 = {:Signature, {1, 3, 6, 1, 4, 1, 11591, 15, 1}, public_key, signature} + {:XferBlob, ttl, markers, signature2, xfinner} end def pack_inner(topic, attrs, severity, data) do @@ -26,7 +27,7 @@ defmodule Floof.Message do data end - def build_outer(source, ttl, markers, secret_key, xfinner) do - {:XferBlob, source, ttl, markers, nil, xfinner} |> sign(secret_key) + def build_outer(ttl, markers, secret_key, xfinner) do + {:XferBlob, ttl, markers, nil, xfinner} |> sign(secret_key) end end diff --git a/lib/floof/pubkey_mgr.ex b/lib/floof/pubkey_mgr.ex deleted file mode 100644 index 456f269..0000000 --- a/lib/floof/pubkey_mgr.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule Floof.PubkeyMgr do - @callback get_pubkey(any(), [{:RelativeDistinguishedName, any(), any()}]) :: - {:ok, :ed25519, binary()} | :error -end - -defmodule Floof.PubkeyMgr.FileDB do - @behaviour Floof.PubkeyMgr - - def get_pubkey(config, source) do - keydb = config.keydb - - if keydb == "" do - :error - else - {:ok, encname} = :FloofProtocol.encode(:RDNSequence, source) - keypath = keydb <> "/" <> Base.url_encode64(encname) - - case File.read(keypath) do - {:ok, data} -> {:ok, :ed25519, data} - {:error, _} -> :error - end - end - end -end diff --git a/mix.exs b/mix.exs index 55c5a84..ca3212d 100644 --- a/mix.exs +++ b/mix.exs @@ -34,10 +34,7 @@ defmodule Floof.MixProject do # these are the markers of form {:RelativeDistinguishedName, oid-as-list(), value()} # which get added to all processed messages set_markers: [], - pubkey_mgr: Floof.PubkeyMgr.FileDB, # file locations - # the keydb is only read, and is used to check message signatures - pubkey_config: %{:keydb => "mock_keydb"}, # the spool dir saves messages in-transit, and is used to prevent RAM OOM spool_dir: "mock_spool", # the sessions file is used for persistence of session data across restarts diff --git a/mock_keydb/AQoJkiaJk_IsZAEZBHRlc3Q= b/mock_keydb/AQoJkiaJk_IsZAEZBHRlc3Q= deleted file mode 100644 index ed14b30..0000000 --- a/mock_keydb/AQoJkiaJk_IsZAEZBHRlc3Q= +++ /dev/null @@ -1 +0,0 @@ -"a?0]}MZݗM \ No newline at end of file diff --git a/test/floof_test.exs b/test/floof_test.exs index 1ca80df..3e0bab2 100644 --- a/test/floof_test.exs +++ b/test/floof_test.exs @@ -8,11 +8,10 @@ defmodule FloofTest do # {:ok, pkname} = :FloofProtocol.encode(:RDNSequence, [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 25}, "test"}]) # :ok = File.write("mock_keydb/" <> Base.url_encode64(pkname), kp.public) - {:ok, secret_key} = File.read("mock_keydb/test01.secret") - source = [{:RelativeDistinguishedName, {0, 9, 2342, 19_200_300, 100, 1, 25}, "test"}] + {:ok, secret_key} = File.read("test/test01.secret") msg_topic = [{:RelativeDistinguishedName, {2, 5, 4, 41}, "test topic"}] msg_inner = Floof.Message.pack_inner(msg_topic, [], :info, <<0, 0>>) - msg_outer = Floof.Message.build_outer(source, 10, [], secret_key, msg_inner) + msg_outer = Floof.Message.build_outer(10, [], secret_key, msg_inner) {:ok, msg_encd} = :FloofProtocol.encode(:ProtoMessage, {:xfer, msg_outer}) Floof.Distributor.register(self()) diff --git a/mock_keydb/test01.secret b/test/test01.secret similarity index 100% rename from mock_keydb/test01.secret rename to test/test01.secret