riverrun / one_time_pass_ecto

No longer maintained - One-time password library with Ecto support (for Elixir)
55 stars 9 forks source link

Incompatibility with Erlang/OTP 24 #9

Closed marcandre closed 3 years ago

marcandre commented 3 years ago

Erlang/OTP 24 dropped :crypto.hmac.

(UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead

One must use :crypto.mac/4 which is OTP 22+

It's not super clear to me how to handle Erlang as a dependency; I'd propose a PR but I'm not sure how to not break compatiblity with OTP < 22.

``` 1) test check totp with default options (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:62 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: token = OneTimePassEcto.Base.gen_totp("MFRGGZDFMZTWQ2LK") stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 3, 56, 206, 215>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/one_time_pass_ecto_test.exs:63: (test) 2) test check hotp using different secret blocks access using original hotp secret (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:45 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: login(user, otp_secret: :second_otp_secret, otp_last: :second_otp_last) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, <<39, 17, 127, 0, 44, 86, 111, 243, 55, 190>>, <<0, 0, 0, 0, 0, 0, 0, 1>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:86: OneTimePassEcto.check_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:69: anonymous fn/5 in OneTimePassEcto.verify/4 (ecto_sql 3.0.3) lib/ecto/adapters/sql.ex:798: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4 (db_connection 2.0.3) lib/db_connection.ex:1349: DBConnection.run_transaction/4 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:67: OneTimePassEcto.verify/4 test/one_time_pass_ecto_test.exs:48: (test) 3) test check totp with default options and alternate secret (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:69 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: token = OneTimePassEcto.Base.gen_totp("E4IX6ABMKZX7GN56") stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, <<39, 17, 127, 0, 44, 86, 111, 243, 55, 190>>, <<0, 0, 0, 0, 3, 56, 206, 215>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/one_time_pass_ecto_test.exs:70: (test) 4) test check hotp with default options (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:24 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: {:ok, %{id: id, otp_last: otp_last}} = login(user, []) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 1>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:86: OneTimePassEcto.check_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:69: anonymous fn/5 in OneTimePassEcto.verify/4 (ecto_sql 3.0.3) lib/ecto/adapters/sql.ex:798: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4 (db_connection 2.0.3) lib/db_connection.ex:1349: DBConnection.run_transaction/4 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:67: OneTimePassEcto.verify/4 test/one_time_pass_ecto_test.exs:26: (test) 5) test disallow totp check with same token (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:76 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: token = OneTimePassEcto.Base.gen_totp("MFRGGZDFMZTWQ2LK") stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 3, 56, 206, 215>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/one_time_pass_ecto_test.exs:77: (test) 6) test disallow totp check with earlier token that is still valid (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:85 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: token = OneTimePassEcto.Base.gen_totp("MFRGGZDFMZTWQ2LK") stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 3, 56, 206, 215>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/one_time_pass_ecto_test.exs:86: (test) 7) test check hotp with updated last (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:35 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: {:ok, %{id: id, otp_last: otp_last}} = login(user, []) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 19>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:86: OneTimePassEcto.check_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:69: anonymous fn/5 in OneTimePassEcto.verify/4 (ecto_sql 3.0.3) lib/ecto/adapters/sql.ex:798: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4 (db_connection 2.0.3) lib/db_connection.ex:1349: DBConnection.run_transaction/4 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:67: OneTimePassEcto.verify/4 test/one_time_pass_ecto_test.exs:37: (test) 8) test check hotp using alternate secret (OneTimePassEctoTest) test/one_time_pass_ecto_test.exs:51 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: {:ok, %{id: id, second_otp_last: otp_last}} = login(user, opts) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, <<39, 17, 127, 0, 44, 86, 111, 243, 55, 190>>, <<0, 0, 0, 0, 0, 0, 0, 1>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:86: OneTimePassEcto.check_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:69: anonymous fn/5 in OneTimePassEcto.verify/4 (ecto_sql 3.0.3) lib/ecto/adapters/sql.ex:798: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4 (db_connection 2.0warning: Supervisor.terminate_child/2 with a PID is deprecated, please use DynamicSupervisor instead (elixir 1.12.0) lib/supervisor.ex:857: Supervisor.terminate_child/2 (db_connection 2.0.3) lib/db_connection/watcher.ex:38: DBConnection.Watcher.handle_info/2 (stdlib 3.15) gen_server.erl:695: :gen_server.try_dispatch/4 (stdlib 3.15) gen_server.erl:771: :gen_server.handle_msg/6 (stdlib 3.15) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 .3) lib/db_connection.ex:1349: DBConnection.run_transaction/4 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto.ex:67: OneTimePassEcto.verify/4 test/one_time_pass_ecto_test.exs:54: (test) 9) test check hotp (OneTimePassEcto.BaseTest) test/base_test.exs:44 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: assert Base.check_hotp("816065", "MFRGGZDFMZTWQ2LK") == 2 stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 1>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 test/base_test.exs:45: (test) 10) test generate hotp (OneTimePassEcto.BaseTest) test/base_test.exs:33 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: assert Base.gen_hotp("MFRGGZDFMZTWQ2LK", 1) == "765705" stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 1>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/base_test.exs:34: (test) 11) test check hotp fails for outside window (OneTimePassEcto.BaseTest) test/base_test.exs:50 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: refute Base.check_hotp("088239", "MFRGGZDFMZTWQ2LK", last: 10) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 11>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:155: OneTimePassEcto.Base.check_token/5 test/base_test.exs:51: (test) .. 12) test check totp (OneTimePassEcto.BaseTest) test/base_test.exs:56 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: assert Base.gen_totp("MFRGGZDFMZTWQ2LK") |> Base.check_totp("MFRGGZDFMZTWQ2LK") stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 3, 56, 206, 215>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/base_test.exs:57: (test) 13) test check totp fails for outside window (OneTimePassEcto.BaseTest) test/base_test.exs:63 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: token = Base.gen_hotp("MFRGGZDFMZTWQ2LK", get_count() - 2) stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 3, 56, 206, 213>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/base_test.exs:64: (test) . 14) test generate hotp with zero padding (OneTimePassEcto.BaseTest) test/base_test.exs:40 ** (UndefinedFunctionError) function :crypto.hmac/3 is undefined or private, use crypto:mac/4 instead code: assert Base.gen_hotp("MFRGGZDFMZTWQ2LK", 19) == "088239" stacktrace: (crypto 5.0.1) :crypto.hmac(:sha, "abcdefghij", <<0, 0, 0, 0, 0, 0, 0, 19>>) (one_time_pass_ecto 1.0.3) lib/one_time_pass_ecto/base.ex:73: OneTimePassEcto.Base.gen_hotp/3 test/base_test.exs:41: (test) Finished in 0.1 seconds (0.00s async, 0.1s sync) 17 tests, 14 failures Randomized with seed 669903 ```
riverrun commented 3 years ago

Thanks for letting me know. I will fix this soon.

marcandre commented 3 years ago

Awesome :-) FYI, the package plug_crypto was updated to tackle the same thing in https://github.com/elixir-plug/plug_crypto/commit/cf901bd2c6694032353072b2c475d18eee7160cf and https://github.com/elixir-plug/plug_crypto/commit/8c1f9271c9a0fb241b1cc970608187246d88d29d

emaiax commented 3 years ago

@marcandre @marcandre FYI, just sent a PR fixing the issue. thanks! :)

riverrun commented 3 years ago

Changes added to version 1.1.

marcandre commented 3 years ago

Thanks so much!