Skip to content

Commit ff0b4d0

Browse files
committed
Rely on CI to test static across versions
1 parent 2e4559c commit ff0b4d0

2 files changed

Lines changed: 41 additions & 53 deletions

File tree

lib/plug/crypto/key_generator.ex

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,15 @@ defmodule Plug.Crypto.KeyGenerator do
3131
3232
"""
3333
def generate(secret, salt, opts \\ []) do
34-
force_legacy_mode = Keyword.get(opts, :force_legacy_mode, false)
3534
iterations = Keyword.get(opts, :iterations, 1000)
3635
length = Keyword.get(opts, :length, 32)
3736
digest = Keyword.get(opts, :digest, :sha256)
3837
cache = Keyword.get(opts, :cache)
39-
generate(secret, salt, iterations, length, digest, force_legacy_mode, cache)
38+
generate(secret, salt, iterations, length, digest, cache)
4039
end
4140

4241
@doc false
4342
def generate(secret, salt, iterations, length, digest, cache) do
44-
generate(secret, salt, iterations, length, digest, false, cache)
45-
end
46-
47-
defp generate(secret, salt, iterations, length, digest, force_legacy_mode, cache) do
4843
cond do
4944
not is_integer(iterations) or iterations < 1 ->
5045
raise ArgumentError, "iterations must be an integer >= 1"
@@ -54,23 +49,13 @@ defmodule Plug.Crypto.KeyGenerator do
5449

5550
true ->
5651
with_cache(cache, {secret, salt, iterations, length, digest}, fn ->
57-
pbkdf2_hmac(digest, secret, salt, iterations, length, force_legacy_mode)
52+
pbkdf2_hmac(digest, secret, salt, iterations, length)
5853
end)
5954
end
6055
rescue
6156
e -> reraise e, Plug.Crypto.prune_args_from_stacktrace(__STACKTRACE__)
6257
end
6358

64-
defp pbkdf2_hmac(digest, secret, salt, iterations, length, force_legacy_mode) do
65-
# TODO: remove when we require OTP 24.2
66-
if not force_legacy_mode and Code.ensure_loaded?(:crypto) and
67-
function_exported?(:crypto, :pbkdf2_hmac, 5) do
68-
:crypto.pbkdf2_hmac(digest, secret, salt, iterations, length)
69-
else
70-
legacy_pbkdf2_hmac(hmac_fun(digest, secret), salt, iterations, length, 1, [], 0)
71-
end
72-
end
73-
7459
defp with_cache(nil, _key, fun), do: fun.()
7560

7661
defp with_cache(ets, key, fun) do
@@ -85,27 +70,46 @@ defmodule Plug.Crypto.KeyGenerator do
8570
end
8671
end
8772

88-
defp legacy_pbkdf2_hmac(_fun, _salt, _iterations, max_length, _block_index, acc, length)
89-
when length >= max_length do
90-
acc
91-
|> IO.iodata_to_binary()
92-
|> binary_part(0, max_length)
93-
end
73+
# TODO: remove when we require OTP 24.2
74+
if Code.ensure_loaded?(:crypto) and function_exported?(:crypto, :pbkdf2_hmac, 5) do
75+
defp pbkdf2_hmac(digest, secret, salt, iterations, length) do
76+
:crypto.pbkdf2_hmac(digest, secret, salt, iterations, length)
77+
end
78+
else
79+
defp pbkdf2_hmac(digest, secret, salt, iterations, length) do
80+
legacy_pbkdf2_hmac(hmac_fun(digest, secret), salt, iterations, length, 1, [], 0)
81+
end
9482

95-
defp legacy_pbkdf2_hmac(fun, salt, iterations, max_length, block_index, acc, length) do
96-
initial = fun.(<<salt::binary, block_index::integer-size(32)>>)
97-
block = iterate(fun, iterations - 1, initial, initial)
98-
length = byte_size(block) + length
83+
defp legacy_pbkdf2_hmac(_fun, _salt, _iterations, max_length, _block_index, acc, length)
84+
when length >= max_length do
85+
acc
86+
|> IO.iodata_to_binary()
87+
|> binary_part(0, max_length)
88+
end
9989

100-
legacy_pbkdf2_hmac(fun, salt, iterations, max_length, block_index + 1, [acc | block], length)
101-
end
90+
defp legacy_pbkdf2_hmac(fun, salt, iterations, max_length, block_index, acc, length) do
91+
initial = fun.(<<salt::binary, block_index::integer-size(32)>>)
92+
block = iterate(fun, iterations - 1, initial, initial)
93+
length = byte_size(block) + length
94+
95+
legacy_pbkdf2_hmac(
96+
fun,
97+
salt,
98+
iterations,
99+
max_length,
100+
block_index + 1,
101+
[acc | block],
102+
length
103+
)
104+
end
102105

103-
defp iterate(_fun, 0, _prev, acc), do: acc
106+
defp iterate(_fun, 0, _prev, acc), do: acc
104107

105-
defp iterate(fun, iteration, prev, acc) do
106-
next = fun.(prev)
107-
iterate(fun, iteration - 1, next, :crypto.exor(next, acc))
108-
end
108+
defp iterate(fun, iteration, prev, acc) do
109+
next = fun.(prev)
110+
iterate(fun, iteration - 1, next, :crypto.exor(next, acc))
111+
end
109112

110-
defp hmac_fun(digest, key), do: &:crypto.mac(:hmac, digest, key, &1)
113+
defp hmac_fun(digest, key), do: &:crypto.mac(:hmac, digest, key, &1)
114+
end
111115
end

test/plug/crypto/key_generator_test.exs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ defmodule Plug.Crypto.KeyGeneratorTest do
1919
end
2020
end
2121

22-
test "it works" do
22+
test "digest :sha works" do
2323
key = generate("password", "salt", iterations: 1, length: 20, digest: :sha)
2424
assert byte_size(key) == 20
2525
assert to_hex(key) == "0c60c80f961f0e71f3a9b524af6012062fe037a6"
@@ -63,12 +63,6 @@ defmodule Plug.Crypto.KeyGeneratorTest do
6363
"6e88be8bad7eae9d9e10aa061224034fed48d03fcbad968b56006784539d5214ce970d912ec2049b04231d47c2eb88506945b26b2325e6adfeeba08895ff9587"
6464
end
6565

66-
test "digest :sha works" do
67-
key = generate("password", "salt", iterations: 1, length: 16, digest: :sha)
68-
assert byte_size(key) == 16
69-
assert to_hex(key) == "0c60c80f961f0e71f3a9b524af601206"
70-
end
71-
7266
test "digest :sha224 works" do
7367
key = generate("password", "salt", iterations: 1, length: 16, digest: :sha224)
7468
assert byte_size(key) == 16
@@ -94,17 +88,7 @@ defmodule Plug.Crypto.KeyGeneratorTest do
9488
end
9589

9690
def generate(secret, salt, opts \\ []) do
97-
key = Plug.Crypto.KeyGenerator.generate(secret, salt, opts)
98-
99-
legacy_key =
100-
Plug.Crypto.KeyGenerator.generate(
101-
secret,
102-
salt,
103-
Keyword.merge(opts, force_legacy_mode: true)
104-
)
105-
106-
assert key == legacy_key
107-
key
91+
Plug.Crypto.KeyGenerator.generate(secret, salt, opts)
10892
end
10993

11094
def to_hex(value), do: Base.encode16(value, case: :lower)

0 commit comments

Comments
 (0)