Salmon creation.

This commit is contained in:
Roger Braun 2017-04-26 14:25:44 +02:00
commit 57bd59e407
3 changed files with 115 additions and 1 deletions

View file

@ -57,7 +57,7 @@ defmodule Pleroma.Web.Salmon do
end
end
defp decode_key("RSA." <> magickey) do
def decode_key("RSA." <> magickey) do
make_integer = fn(bin) ->
list = :erlang.binary_to_list(bin)
Enum.reduce(list, 0, fn (el, acc) -> (acc <<< 8) ||| el end)
@ -70,4 +70,58 @@ defmodule Pleroma.Web.Salmon do
{:RSAPublicKey, modulus, exponent}
end
def encode_key({:RSAPublicKey, modulus, exponent}) do
modulus_enc = :binary.encode_unsigned(modulus) |> Base.url_encode64
exponent_enc = :binary.encode_unsigned(exponent) |> Base.url_encode64
"RSA.#{modulus_enc}.#{exponent_enc}"
end
def generate_rsa_pem do
port = Port.open({:spawn, "openssl genrsa"}, [:binary])
{:ok, pem} = receive do
{^port, {:data, pem}} -> {:ok, pem}
end
Port.close(port)
if Regex.match?(~r/RSA PRIVATE KEY/, pem) do
{:ok, pem}
else
:error
end
end
def keys_from_pem(pem) do
[private_key_code] = :public_key.pem_decode(pem)
private_key = :public_key.pem_entry_decode(private_key_code)
{:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} = private_key
public_key = {:RSAPublicKey, modulus, exponent}
{:ok, private_key, public_key}
end
def encode(private_key, doc) do
type = "application/atom+xml"
encoding = "base64url"
alg = "RSA-SHA256"
signed_text = [doc, type, encoding, alg]
|> Enum.map(&Base.url_encode64/1)
|> Enum.join(".")
signature = :public_key.sign(signed_text, :sha256, private_key) |> to_string |> Base.url_encode64
doc_base64= doc |> Base.url_encode64
# Don't need proper xml building, these strings are safe to leave unescaped
salmon = """
<?xml version="1.0" encoding="UTF-8"?>
<me:env xmlns:me="http://salmon-protocol.org/ns/magic-env">
<me:data type="application/atom+xml">#{doc_base64}</me:data>
<me:encoding>#{encoding}</me:encoding>
<me:alg>#{alg}</me:alg>
<me:sig>#{signature}</me:sig>
</me:env>
"""
{:ok, salmon}
end
end