diff options
author | Nick Vatamaniuc <vatamane@apache.org> | 2021-05-17 01:35:27 -0400 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2021-05-19 15:22:25 -0400 |
commit | e632b45cc556281887361f3e25196ddf5e800363 (patch) | |
tree | edb9e3d32821bf0077c2e079090c64589ff9a3f8 | |
parent | 7b85048ec2566fe9b2eedabd51b992d5ac52b9a3 (diff) | |
download | couchdb-e632b45cc556281887361f3e25196ddf5e800363.tar.gz |
Erlang 24 support for 3.x branch
The main fix is to switch crypto functions to use the new versions for
22+ while keeping Erlang 20 still working.
```
crypto:hmac(Alg, Key, Message) -> crypto:mac(hmac, Alg, Key, Message)
```
-rw-r--r-- | rebar.config.script | 8 | ||||
-rw-r--r-- | src/couch/src/couch_hotp.erl | 2 | ||||
-rw-r--r-- | src/couch/src/couch_httpd_auth.erl | 6 | ||||
-rw-r--r-- | src/couch/src/couch_passwords.erl | 4 | ||||
-rw-r--r-- | src/couch/src/couch_util.erl | 26 | ||||
-rw-r--r-- | src/jwtf/src/jwtf.erl | 29 | ||||
-rw-r--r-- | test/elixir/test/proxyauth_test.exs | 6 |
7 files changed, 68 insertions, 13 deletions
diff --git a/rebar.config.script b/rebar.config.script index cac648d05..c14772e2f 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -149,7 +149,7 @@ DepDescs = [ {b64url, "b64url", {tag, "1.0.2"}}, {ets_lru, "ets-lru", {tag, "1.1.0"}}, {khash, "khash", {tag, "1.1.0"}}, -{snappy, "snappy", {tag, "CouchDB-1.0.6"}}, +{snappy, "snappy", {tag, "CouchDB-1.0.7"}}, %% Non-Erlang deps {docs, {url, "https://github.com/apache/couchdb-documentation"}, @@ -157,12 +157,12 @@ DepDescs = [ {fauxton, {url, "https://github.com/apache/couchdb-fauxton"}, {tag, "v1.2.6"}, [raw]}, %% Third party deps -{folsom, "folsom", {tag, "CouchDB-0.8.3"}}, +{folsom, "folsom", {tag, "CouchDB-0.8.4"}}, {hyper, "hyper", {tag, "CouchDB-2.2.0-6"}}, {ibrowse, "ibrowse", {tag, "CouchDB-4.4.2-2"}}, {jiffy, "jiffy", {tag, "CouchDB-1.0.5-1"}}, {mochiweb, "mochiweb", {tag, "v2.20.0"}}, -{meck, "meck", {tag, "0.8.8"}}, +{meck, "meck", {tag, "0.9.2"}}, {recon, "recon", {tag, "2.5.0"}} ]. @@ -196,7 +196,7 @@ ErlOpts = case os:getenv("ERL_OPTS") of end. AddConfig = [ - {require_otp_vsn, "19|20|21|22|23"}, + {require_otp_vsn, "19|20|21|22|23|24"}, {deps_dir, "src"}, {deps, lists:map(MakeDep, DepDescs ++ OptionalDeps)}, {sub_dirs, SubDirs}, diff --git a/src/couch/src/couch_hotp.erl b/src/couch/src/couch_hotp.erl index 9a620fa87..4ba81c9bf 100644 --- a/src/couch/src/couch_hotp.erl +++ b/src/couch/src/couch_hotp.erl @@ -16,7 +16,7 @@ generate(Alg, Key, Counter, OutputLen) when is_atom(Alg), is_binary(Key), is_integer(Counter), is_integer(OutputLen) -> - Hmac = crypto:hmac(Alg, Key, <<Counter:64>>), + Hmac = couch_util:hmac(Alg, Key, <<Counter:64>>), Offset = binary:last(Hmac) band 16#f, Code = ((binary:at(Hmac, Offset) band 16#7f) bsl 24) + diff --git a/src/couch/src/couch_httpd_auth.erl b/src/couch/src/couch_httpd_auth.erl index 7d728e647..b702c346f 100644 --- a/src/couch/src/couch_httpd_auth.erl +++ b/src/couch/src/couch_httpd_auth.erl @@ -175,7 +175,7 @@ proxy_auth_user(Req) -> undefined -> Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), roles=Roles}}; Secret -> - ExpectedToken = couch_util:to_hex(crypto:hmac(sha, Secret, UserName)), + ExpectedToken = couch_util:to_hex(couch_util:hmac(sha, Secret, UserName)), case header_value(Req, XHeaderToken) of Token when Token == ExpectedToken -> Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), @@ -255,7 +255,7 @@ cookie_authentication_handler(#httpd{mochi_req=MochiReq}=Req, AuthModule) -> {ok, UserProps, _AuthCtx} -> UserSalt = couch_util:get_value(<<"salt">>, UserProps, <<"">>), FullSecret = <<Secret/binary, UserSalt/binary>>, - ExpectedHash = crypto:hmac(sha, FullSecret, User ++ ":" ++ TimeStr), + ExpectedHash = couch_util:hmac(sha, FullSecret, User ++ ":" ++ TimeStr), Hash = ?l2b(HashStr), Timeout = list_to_integer( config:get("couch_httpd_auth", "timeout", "600")), @@ -303,7 +303,7 @@ cookie_auth_header(_Req, _Headers) -> []. cookie_auth_cookie(Req, User, Secret, TimeStamp) -> SessionData = User ++ ":" ++ erlang:integer_to_list(TimeStamp, 16), - Hash = crypto:hmac(sha, Secret, SessionData), + Hash = couch_util:hmac(sha, Secret, SessionData), mochiweb_cookies:cookie("AuthSession", couch_util:encodeBase64Url(SessionData ++ ":" ++ ?b2l(Hash)), [{path, "/"}] ++ cookie_scheme(Req) ++ max_age() ++ cookie_domain() ++ same_site()). diff --git a/src/couch/src/couch_passwords.erl b/src/couch/src/couch_passwords.erl index baf78f5d5..87ed15144 100644 --- a/src/couch/src/couch_passwords.erl +++ b/src/couch/src/couch_passwords.erl @@ -114,12 +114,12 @@ pbkdf2(_Password, _Salt, Iterations, _BlockIndex, Iteration, _Prev, Acc) when Iteration > Iterations -> Acc; pbkdf2(Password, Salt, Iterations, BlockIndex, 1, _Prev, _Acc) -> - InitialBlock = crypto:hmac(sha, Password, + InitialBlock = couch_util:hmac(sha, Password, <<Salt/binary,BlockIndex:32/integer>>), pbkdf2(Password, Salt, Iterations, BlockIndex, 2, InitialBlock, InitialBlock); pbkdf2(Password, Salt, Iterations, BlockIndex, Iteration, Prev, Acc) -> - Next = crypto:hmac(sha, Password, Prev), + Next = couch_util:hmac(sha, Password, Prev), pbkdf2(Password, Salt, Iterations, BlockIndex, Iteration + 1, Next, crypto:exor(Next, Acc)). diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl index 95780e8cc..d1f494006 100644 --- a/src/couch/src/couch_util.erl +++ b/src/couch/src/couch_util.erl @@ -41,6 +41,7 @@ -export([check_md5/2]). -export([set_mqd_off_heap/1]). -export([set_process_priority/2]). +-export([hmac/3]). -include_lib("couch/include/couch_db.hrl"). @@ -775,3 +776,28 @@ check_config_blacklist(Section) -> _ -> ok end. + + +-ifdef(OTP_RELEASE). + +-if(?OTP_RELEASE >= 22). + +% OTP >= 22 +hmac(Alg, Key, Message) -> + crypto:mac(hmac, Alg, Key, Message). + +-else. + +% OTP >= 21, < 22 +hmac(Alg, Key, Message) -> + crypto:hmac(Alg, Key, Message). + +-endif. % -if(?OTP_RELEASE >= 22) + +-else. + +% OTP < 21 +hmac(Alg, Key, Message) -> + crypto:hmac(Alg, Key, Message). + +-endif. % -ifdef(OTP_RELEASE) diff --git a/src/jwtf/src/jwtf.erl b/src/jwtf/src/jwtf.erl index a0bbf1fc1..4c4f80c70 100644 --- a/src/jwtf/src/jwtf.erl +++ b/src/jwtf/src/jwtf.erl @@ -65,7 +65,7 @@ encode(Header = {HeaderProps}, Claims, Key) -> {public_key, Algorithm} -> public_key:sign(Message, Algorithm, Key); {hmac, Algorithm} -> - crypto:hmac(Algorithm, Key, Message) + hmac(Algorithm, Key, Message) end, EncodedSignatureOrMac = b64url:encode(SignatureOrMac), {ok, <<Message/binary, $., EncodedSignatureOrMac/binary>>} @@ -290,7 +290,7 @@ public_key_verify(Algorithm, Message, Signature, PublicKey) -> hmac_verify(Algorithm, Message, HMAC, SecretKey) -> - case crypto:hmac(Algorithm, SecretKey, Message) of + case hmac(Algorithm, SecretKey, Message) of HMAC -> ok; _ -> @@ -352,6 +352,31 @@ prop(Prop, Props) -> proplists:get_value(Prop, Props). +-ifdef(OTP_RELEASE). + +-if(?OTP_RELEASE >= 22). + +% OTP >= 22 +hmac(Alg, Key, Message) -> + crypto:mac(hmac, Alg, Key, Message). + +-else. + +% OTP >= 21, < 22 +hmac(Alg, Key, Message) -> + crypto:hmac(Alg, Key, Message). + +-endif. % -if(?OTP_RELEASE >= 22) + +-else. + +% OTP < 21 +hmac(Alg, Key, Message) -> + crypto:hmac(Alg, Key, Message). + +-endif. % -ifdef(OTP_RELEASE) + + -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). diff --git a/test/elixir/test/proxyauth_test.exs b/test/elixir/test/proxyauth_test.exs index 6f2d49a53..6bf21920b 100644 --- a/test/elixir/test/proxyauth_test.exs +++ b/test/elixir/test/proxyauth_test.exs @@ -63,7 +63,11 @@ defmodule ProxyAuthTest do end defp hex_hmac_sha1(secret, message) do - signature = :crypto.hmac(:sha, secret, message) + signature = case :erlang.system_info(:otp_release) do + '20' -> :crypto.hmac(:sha, secret, message) + '21' -> :crypto.hmac(:sha, secret, message) + _ -> :crypto.mac(:hmac, :sha, secret, message) + end Base.encode16(signature, case: :lower) end |