Skip to content

Commit

Permalink
Fix RSA modulus bit size calculation and OTP 20 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
jayjun committed Jul 9, 2017
1 parent 3d0cd3c commit 2a13b60
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 14 deletions.
16 changes: 12 additions & 4 deletions lib/json_web_token/algorithm/rsa.ex
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,25 @@ defmodule JsonWebToken.Algorithm.Rsa do
end

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

defp validate_params(sha_bits, key) do
Common.validate_bits(sha_bits)
validate_key_size(key)
end

# http://tools.ietf.org/html/rfc7518#section-3.3
defp validate_key_size(a_key) do
key = Util.validate_present(a_key)
weak_key(bit_size(modulus key) < @key_bits_min)
defp validate_key_size(key) when is_list(key) do
key = Util.validate_present(key) |> modulus()
weak_key(bit_size(key) < @key_bits_min)
end

defp validate_key_size(key) do
key = Util.validate_present(key)
weak_key(bit_size(key) < @key_bits_min)
end

defp weak_key(true), do: raise "RSA modulus too short"
Expand Down
10 changes: 4 additions & 6 deletions lib/json_web_token/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ defmodule JsonWebToken.Util do
defp arithmetic_compare("", "", acc), do: acc

@doc """
Return the string passed in, unless it is nil or an empty string
Return the parameter passed in, unless it is nil or an empty string
## Example
iex> JsonWebToken.Util.validate_present("a")
"a"
"""
def validate_present(param), do: validate_present(param, param == "")

defp validate_present(nil, _), do: raise "Param nil"
defp validate_present(_, true), do: raise "Param blank"
defp validate_present(param, _), do: param
def validate_present(nil), do: raise "Param nil"
def validate_present(""), do: raise "Param blank"
def validate_present(param), do: param
end
3 changes: 2 additions & 1 deletion test/json_web_token/algorithm/rsa_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ defmodule JsonWebToken.Algorithm.RsaTest do
end

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

Expand Down
6 changes: 3 additions & 3 deletions test/json_web_token/algorithm/rsa_util_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ defmodule JsonWebToken.Algorithm.RsaUtilTest do
test "private_key" do
key = RsaUtil.private_key(@path_to_keys, "private_key.pem")
assert length(key) == 3
assert byte_size(Rsa.modulus key) == 261
assert byte_size(Rsa.modulus key) == 256
end

test "public_key" do
key = RsaUtil.public_key(@path_to_keys, "public_key.pem")
assert length(key) == 2
assert byte_size(Rsa.modulus key) == 261
assert byte_size(Rsa.modulus key) == 256
end

test "private key with ASN.1 header" do
key = RsaUtil.private_key(@path_to_keys, "private_key_asn1_header.pem")
assert length(key) == 3
assert byte_size(Rsa.modulus key) == 261
assert byte_size(Rsa.modulus key) == 256
end

test "private key passed in directly" do
Expand Down

0 comments on commit 2a13b60

Please sign in to comment.