Current section
Files
Jump to
Current section
Files
lib/elixir_elliptic_curve.ex
defmodule ECC do
use GenServer
def init([pem]) do
{:ok, %{
public: ECC.Crypto.parse_public_key(pem),
private: ECC.Crypto.parse_private_key(pem)
}}
end
def handle_call(:get_public_key, _from, keys) do
if keys.public do
{:reply, {:ok, keys.public}, keys}
else
{:reply, {:error, :no_public_key}, keys}
end
end
def handle_call({:sign, msg, hash_type}, _from, keys) do
{:reply, {:ok, ECC.Crypto.sign(msg, hash_type, keys.private)}, keys}
end
def handle_call({:verify_signature, msg, signature, public_key, hash_type}, _from, keys) do
result = ECC.Crypto.verify_signature(msg, signature, hash_type, public_key)
{:reply, {:ok, result}, keys}
end
end
defmodule ECC.Crypto do
def parse_public_key(pem) do
try do
pem_keys = :public_key.pem_decode(pem)
ec_params =
Enum.find(pem_keys, fn(k) -> elem(k,0) == :OTPEcpkParameters end)
|> put_elem(0, :EcpkParameters)
|> :public_key.pem_entry_decode
pem_public =
Enum.find(pem_keys, fn(k) -> elem(k,0) == :SubjectPublicKeyInfo end)
|> elem(1)
ec_point = :public_key.der_decode(:SubjectPublicKeyInfo, pem_public)
|> elem(2)
|> elem(1)
{{:ECPoint, ec_point}, ec_params}
rescue
_ -> nil
end
end
def parse_private_key(pem) do
try do
:public_key.pem_decode(pem)
|> Enum.find(fn(k) -> elem(k,0) == :ECPrivateKey end)
|> :public_key.pem_entry_decode
rescue
_ -> nil
end
end
def sign(msg, hash_type, private_key) do
try do
:public_key.sign msg, hash_type, private_key
rescue
_ -> nil
end
end
def verify_signature(msg, signature, hash_type, public_key) do
try do
:public_key.verify(msg, hash_type, signature, public_key)
rescue
_ -> nil
end
end
end