Skip to content

Commit 2a13b60

Browse files
committed
Fix RSA modulus bit size calculation and OTP 20 compatibility
1 parent 3d0cd3c commit 2a13b60

File tree

4 files changed

+21
-14
lines changed

4 files changed

+21
-14
lines changed

lib/json_web_token/algorithm/rsa.ex

+12-4
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,25 @@ defmodule JsonWebToken.Algorithm.Rsa do
4343
end
4444

4545
@doc "RSA key modulus, n"
46-
def modulus(key), do: :crypto.mpint(Enum.at key, 1)
46+
def modulus([_exponent, modulus | _rest]) do
47+
bytes_list = Integer.digits(modulus, 256)
48+
:erlang.list_to_binary(bytes_list)
49+
end
4750

4851
defp validate_params(sha_bits, key) do
4952
Common.validate_bits(sha_bits)
5053
validate_key_size(key)
5154
end
5255

5356
# http://tools.ietf.org/html/rfc7518#section-3.3
54-
defp validate_key_size(a_key) do
55-
key = Util.validate_present(a_key)
56-
weak_key(bit_size(modulus key) < @key_bits_min)
57+
defp validate_key_size(key) when is_list(key) do
58+
key = Util.validate_present(key) |> modulus()
59+
weak_key(bit_size(key) < @key_bits_min)
60+
end
61+
62+
defp validate_key_size(key) do
63+
key = Util.validate_present(key)
64+
weak_key(bit_size(key) < @key_bits_min)
5765
end
5866

5967
defp weak_key(true), do: raise "RSA modulus too short"

lib/json_web_token/util.ex

+4-6
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,13 @@ defmodule JsonWebToken.Util do
2626
defp arithmetic_compare("", "", acc), do: acc
2727

2828
@doc """
29-
Return the string passed in, unless it is nil or an empty string
29+
Return the parameter passed in, unless it is nil or an empty string
3030
3131
## Example
3232
iex> JsonWebToken.Util.validate_present("a")
3333
"a"
3434
"""
35-
def validate_present(param), do: validate_present(param, param == "")
36-
37-
defp validate_present(nil, _), do: raise "Param nil"
38-
defp validate_present(_, true), do: raise "Param blank"
39-
defp validate_present(param, _), do: param
35+
def validate_present(nil), do: raise "Param nil"
36+
def validate_present(""), do: raise "Param blank"
37+
def validate_present(param), do: param
4038
end

test/json_web_token/algorithm/rsa_test.exs

+2-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ defmodule JsonWebToken.Algorithm.RsaTest do
5959
end
6060

6161
test "sign/3 w private_key size < key_bits_min raises" do
62+
# private_key_weak.pem holds a 2000-bit key
6263
private_key = RsaUtil.private_key(@path_to_keys, "private_key_weak.pem")
63-
assert byte_size(Rsa.modulus private_key) == 255
64+
assert byte_size(Rsa.modulus private_key) == 250
6465
invalid_key(private_key, "RSA modulus too short")
6566
end
6667

test/json_web_token/algorithm/rsa_util_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ defmodule JsonWebToken.Algorithm.RsaUtilTest do
99
test "private_key" do
1010
key = RsaUtil.private_key(@path_to_keys, "private_key.pem")
1111
assert length(key) == 3
12-
assert byte_size(Rsa.modulus key) == 261
12+
assert byte_size(Rsa.modulus key) == 256
1313
end
1414

1515
test "public_key" do
1616
key = RsaUtil.public_key(@path_to_keys, "public_key.pem")
1717
assert length(key) == 2
18-
assert byte_size(Rsa.modulus key) == 261
18+
assert byte_size(Rsa.modulus key) == 256
1919
end
2020

2121
test "private key with ASN.1 header" do
2222
key = RsaUtil.private_key(@path_to_keys, "private_key_asn1_header.pem")
2323
assert length(key) == 3
24-
assert byte_size(Rsa.modulus key) == 261
24+
assert byte_size(Rsa.modulus key) == 256
2525
end
2626

2727
test "private key passed in directly" do

0 commit comments

Comments
 (0)