From 4d7ef4a18d714285d457cc37a5166772a3c385f9 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Thu, 31 Oct 2019 22:45:34 -0400 Subject: [PATCH] add cryptor --- config/config.exs | 1 + config/prod.secret.exs | 1 + lib/philomena/users/encryptor.ex | 19 +++++++++++++++++++ lib/philomena/users/user.ex | 17 +++++++++++++++++ mix.exs | 3 ++- mix.lock | 2 ++ 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 lib/philomena/users/encryptor.ex diff --git a/config/config.exs b/config/config.exs index 63dcf03f..e05788d9 100644 --- a/config/config.exs +++ b/config/config.exs @@ -11,6 +11,7 @@ config :philomena, ecto_repos: [Philomena.Repo], elasticsearch_url: "http://localhost:9200", password_pepper: "dn2e0EpZrvBLoxUM3gfQveBhjf0bG/6/bYhrOyq3L3hV9hdo/bimJ+irbDWsuXLP", + otp_secret_key: "Wn7O/8DD+qxL0X4X7bvT90wOkVGcA90bIHww4twR03Ci//zq7PnMw8ypqyyT/b/C", image_url_root: "/img" config :philomena, :pow, diff --git a/config/prod.secret.exs b/config/prod.secret.exs index 0e250c91..690ffdbb 100644 --- a/config/prod.secret.exs +++ b/config/prod.secret.exs @@ -16,6 +16,7 @@ config :bcrypt_elixir, config :philomena, password_pepper: System.get_env("PASSWORD_PEPPER"), + otp_secret_key: System.get_env("OTP_SECRET_KEY"), image_url_root: System.get_env("IMAGE_URL_ROOT") config :philomena, Philomena.Repo, diff --git a/lib/philomena/users/encryptor.ex b/lib/philomena/users/encryptor.ex new file mode 100644 index 00000000..6458bc4b --- /dev/null +++ b/lib/philomena/users/encryptor.ex @@ -0,0 +1,19 @@ +defmodule Philomena.Users.Encryptor do + def decrypt_model(secret, iv, salt) do + # attr_encrypted encoding scheme + secret = Base.decode64!(secret, ignore: :whitespace) + iv = Base.decode64!(iv, ignore: :whitespace) + <> = salt + salt = Base.decode64!(salt, ignore: :whitespace) + + {:ok, key} = :pbkdf2.pbkdf2(:sha, otp_secret(), salt, 2000, 32) + auth_tag = :binary.part(secret, byte_size(secret), -16) + msg = :binary.part(secret, 0, byte_size(secret) - 16) + + :crypto.crypto_one_time_aead(:aes_256_gcm, key, iv, msg, "", auth_tag, false) + end + + defp otp_secret do + Application.get_env(:philomena, :otp_secret_key) + end +end diff --git a/lib/philomena/users/user.ex b/lib/philomena/users/user.ex index 9a4b6307..612310f8 100644 --- a/lib/philomena/users/user.ex +++ b/lib/philomena/users/user.ex @@ -106,5 +106,22 @@ defmodule Philomena.Users.User do |> pow_extension_changeset(attrs) |> cast(attrs, []) |> validate_required([]) + |> put_otp_secret() end + + def otp_secret(%{encrypted_otp_secret: x} = user) when x not in [nil, ""] do + Philomena.Users.Encryptor.decrypt_model( + user.encrypted_otp_secret, + user.encrypted_otp_secret_iv, + user.encrypted_otp_secret_salt + ) + end + + def otp_secret(_user), do: nil + + defp put_otp_secret(%{valid?: true} = changeset) do + + end + + defp put_otp_secret(changeset), do: changeset end diff --git a/mix.exs b/mix.exs index 05e92221..090c0c67 100644 --- a/mix.exs +++ b/mix.exs @@ -53,7 +53,8 @@ defmodule Philomena.MixProject do {:nimble_parsec, "~> 0.5.1"}, {:canary, "~> 1.1.1"}, {:scrivener_ecto, "~> 2.0"}, - {:elixir2fa, "~> 0.1.0"} + {:elixir2fa, "~> 0.1.0"}, + {:pbkdf2, "~> 2.0"} ] end diff --git a/mix.lock b/mix.lock index 9a40e583..45273bd1 100644 --- a/mix.lock +++ b/mix.lock @@ -27,6 +27,8 @@ "neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, + "pbkdf2": {:hex, :pbkdf2, "2.0.0", "11c23279fded5c0027ab3996cfae77805521d7ef4babde2bd7ec04a9086cf499", [:rebar3], [], "hexpm"}, + "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.0.2", "3791717374498a605e7e864bc77a7dd3221e1d035750b3af3df5af632f0fc947", [:mix], [{:comeonin, "~> 5.1", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix": {:hex, :phoenix, "1.4.10", "619e4a545505f562cd294df52294372d012823f4fd9d34a6657a8b242898c255", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},