First
[anni] / lib / pleroma / keys.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Keys do
6   # Native generation of RSA keys is only available since OTP 20+ and in default build conditions
7   # We try at compile time to generate natively an RSA key otherwise we fallback on the old way.
8   try do
9     _ = :public_key.generate_key({:rsa, 2048, 65_537})
10
11     def generate_rsa_pem do
12       key = :public_key.generate_key({:rsa, 2048, 65_537})
13       entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
14       pem = :public_key.pem_encode([entry]) |> String.trim_trailing()
15       {:ok, pem}
16     end
17   rescue
18     _ ->
19       def generate_rsa_pem do
20         port = Port.open({:spawn, "openssl genrsa"}, [:binary])
21
22         {:ok, pem} =
23           receive do
24             {^port, {:data, pem}} -> {:ok, pem}
25           end
26
27         Port.close(port)
28
29         if Regex.match?(~r/RSA PRIVATE KEY/, pem) do
30           {:ok, pem}
31         else
32           :error
33         end
34       end
35   end
36
37   def keys_from_pem(pem) do
38     with [private_key_code] <- :public_key.pem_decode(pem),
39          private_key <- :public_key.pem_entry_decode(private_key_code),
40          {:RSAPrivateKey, _, modulus, exponent, _, _, _, _, _, _, _} <- private_key do
41       {:ok, private_key, {:RSAPublicKey, modulus, exponent}}
42     else
43       error -> {:error, error}
44     end
45   end
46 end