Current section

Files

Jump to
ca lib services csr.ex
Raw

lib/services/csr.ex

defmodule CA.CSR do
@moduledoc "CA/CSR library."
def ca do root("secp384r1", [rdn: "/C=UA/L=Київ/O=SYNRC/CN=CA"]) end
def server(name) do server("secp384r1", [rdn: "/C=UA/L=Київ/O=SYNRC/CN=#{name}", cn: "#{name}"]) end
def client(name) do client("secp384r1", [rdn: "/C=UA/L=Київ/O=SYNRC/CN=#{name}", cn: "#{name}"]) end
def dir(profile) do "synrc/ecc/#{profile}/" end
def root(profile, [rdn: rdn]) do
:filelib.ensure_dir dir(profile)
ca_key = X509.PrivateKey.new_ec(:erlang.binary_to_atom(profile))
:logger.info ~c"CSR CMP DN ~p~n", [rdn]
ca = X509.Certificate.self_signed(ca_key, rdn, template: %X509.Certificate.Template{
validity: round(25 * 365.2425), # 25 years
hash: :sha256,
extensions: [
basic_constraints: X509.Certificate.Extension.basic_constraints(true, 1),
key_usage: X509.Certificate.Extension.key_usage([:digitalSignature, :keyCertSign, :cRLSign]),
subject_key_identifier: true,
authority_key_identifier: true
]
})
der = :public_key.der_encode(:ECPrivateKey, ca_key)
pem = :public_key.pem_encode([{:ECPrivateKey, der, :not_encrypted}])
:file.write_file "#{dir(profile)}/ca.key", pem
:file.write_file "#{dir(profile)}/ca.pem", X509.Certificate.to_pem(ca)
{ca_key, ca}
end
def server(profile, [rdn: rdn, cn: user]) do
{ca_key, ca} = read_ca(profile)
:filelib.ensure_dir dir(profile)
priv = X509.PrivateKey.new_ec(:erlang.binary_to_atom(profile))
der = :public_key.der_encode(:ECPrivateKey, priv)
pem = :public_key.pem_encode([{:ECPrivateKey, der, :not_encrypted}])
:file.write_file("#{dir(profile)}/#{user}.key", pem)
:logger.info ~c"CSR SERVER DN ~p~n", [rdn]
csr = X509.CSR.new(priv, rdn, extension_request: [
X509.Certificate.Extension.subject_alt_name(["synrc.com"])])
:file.write_file("#{dir(profile)}/#{user}.csr", X509.CSR.to_pem(csr))
true = X509.CSR.valid?(csr)
subject = X509.CSR.subject(csr)
server = X509.Certificate.new(X509.CSR.public_key(csr),
subject, ca, ca_key, extensions: [subject_alt_name:
X509.Certificate.Extension.subject_alt_name(["synrc.com"]) ])
:file.write_file "#{dir(profile)}/#{user}.cer", X509.Certificate.to_pem(server)
csr
end
def client(profile, [rdn: rdn, cn: user]) do
priv = X509.PrivateKey.new_ec(:erlang.binary_to_atom(profile))
der = :public_key.der_encode(:ECPrivateKey, priv)
pem = :public_key.pem_encode([{:ECPrivateKey, der, :not_encrypted}])
:file.write_file("#{dir(profile)}/#{user}.key", pem)
:logger.info ~c"CSR CLIENT DN ~p~n", [rdn]
csr = X509.CSR.new(priv, rdn, extension_request: [
X509.Certificate.Extension.subject_alt_name(["synrc.com"])])
:file.write_file("#{dir(profile)}/#{user}.csr", X509.CSR.to_pem(csr))
csr
end
def init(profile) do
case :filelib.is_regular("#{CA.CSR.dir(profile)}/ca.key") do
false -> root(profile, [rdn: "/C=UA/L=Київ/O=SYNRC/CN=CA"])
true -> []
end
end
def read_ca(profile) do
init(profile)
{:ok, ca_key_bin} = :file.read_file "#{CA.CSR.dir(profile)}/ca.key"
{:ok, ca_bin} = :file.read_file "#{CA.CSR.dir(profile)}/ca.pem"
{:ok, ca_key} = X509.PrivateKey.from_pem ca_key_bin
{:ok, ca} = X509.Certificate.from_pem ca_bin
{ca_key, ca}
end
def read_ca_public(profile) do
init(profile)
{:ok, ca_bin} = :file.read_file "#{CA.CSR.dir(profile)}/ca.pem"
{:ok, ca} = X509.Certificate.from_pem ca_bin
{:ok, bin} = :"PKIX1Explicit88".encode(:Certificate, CA.RDN.encodeAttrsCert(ca))
bin
end
end