diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5fec189c..8a9ef527 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -157,7 +157,6 @@ jobs: matrix: platform: - linux/amd64 - - linux/arm64 steps: - name: Prepare run: | diff --git a/lib/wanderer_app/vault.ex b/lib/wanderer_app/vault.ex index adfd087b..f5f10e76 100644 --- a/lib/wanderer_app/vault.ex +++ b/lib/wanderer_app/vault.ex @@ -4,24 +4,134 @@ defmodule WandererApp.Vault do @impl GenServer def init(config) do cipher_key = decode_env!("CLOAK_KEY") + fallback_cipher_key = decode_env!("FALLBACK_CLOAK_KEY") config = Keyword.put(config, :ciphers, default: { Cloak.Ciphers.AES.GCM, - tag: "AES.GCM.V1", - key: cipher_key, - iv_length: 12 + tag: "AES.GCM.V1", key: cipher_key, iv_length: 12 + }, + fallback: { + Cloak.Ciphers.AES.GCM, + tag: "AES.GCM.V1", key: fallback_cipher_key, iv_length: 12 } ) {:ok, config} end - defp decode_env!(var) do - key = System.get_env(var) - if is_nil(key), - do: raise("No environment variable found for #{var}"), - else: Base.decode64!(key) + @impl Cloak.Vault + def encrypt(plaintext) do + with {:ok, config} <- Cloak.Vault.read_config(@table_name) do + Cloak.Vault.encrypt(config, plaintext) + end + end + + @impl Cloak.Vault + def encrypt!(plaintext) do + case Cloak.Vault.read_config(@table_name) do + {:ok, config} -> + Cloak.Vault.encrypt!(config, plaintext) + + {:error, error} -> + raise error + end + end + + @impl Cloak.Vault + def encrypt(plaintext, label) do + with {:ok, config} <- Cloak.Vault.read_config(@table_name) do + Cloak.Vault.encrypt(config, plaintext, label) + end + end + + @impl Cloak.Vault + def encrypt!(plaintext, label) do + case Cloak.Vault.read_config(@table_name) do + {:ok, config} -> + Cloak.Vault.encrypt!(config, plaintext, label) + + {:error, error} -> + raise error + end + end + + @impl Cloak.Vault + def decrypt(ciphertext) do + with {:ok, config} <- Cloak.Vault.read_config(@table_name) do + decrypt(config, ciphertext) + end + end + + @impl Cloak.Vault + def decrypt!(ciphertext) do + case Cloak.Vault.read_config(@table_name) do + {:ok, config} -> + decrypt!(config, ciphertext) + + {:error, error} -> + raise error + end + end + + defp decode_env!(var, fallback_key \\ "OtPJXGfKNyOMWI7TdpcWgOlyNtD9AGSfoAdvEuTQIno=") do + var + |> System.get_env(fallback_key) + |> Base.decode64!() + end + + @doc false + def decrypt(config, ciphertext) do + case find_module_to_decrypt(config, ciphertext) do + nil -> + {:error, Cloak.MissingCipher.exception(vault: config[:vault], ciphertext: ciphertext)} + + {_label, {module, opts}} -> + case module.decrypt(ciphertext, opts) do + {:ok, :error} -> + case find_fallback_module_to_decrypt(config, ciphertext) do + nil -> + {:ok, :error} + + {_label, {module, opts}} -> + module.decrypt(ciphertext, opts) + end + + {:ok, plaintext} -> + {:ok, plaintext} + + error -> + error + end + end + end + + @doc false + def decrypt!(config, ciphertext) do + case decrypt(config, ciphertext) do + {:ok, plaintext} -> + plaintext + + {:error, error} -> + raise error + end + end + + defp find_module_to_decrypt(config, ciphertext) do + IO.inspect("find_module_to_decrypt") + IO.inspect(config) + + Enum.find(config[:ciphers], fn {_label, {module, opts}} -> + module.can_decrypt?(ciphertext, opts) + end) + end + + defp find_fallback_module_to_decrypt(config, ciphertext) do + IO.inspect("find_fallback_module_to_decrypt") + + Enum.find(config[:ciphers], fn {label, _} -> + label == :fallback + end) end end