Current section
Files
Jump to
Current section
Files
lib/services/est.ex
defmodule CA.EST do
@moduledoc "CA/EST TLS HTTP server."
use Plug.Router
plug :match
plug :dispatch
plug Plug.Parsers, parsers: [:json], json_decoder: Jason
def integer(x) do {:ok, v} = :"EST".encode(:Int, x) ; v end
def decodeInteger(x) do {:ok, v} = :"EST".decode(:Int, x) ; v end
def objectIdentifier(x) do {:ok, v} = :"EST".encode(:OID, x) ; v end
def decodeObjectIdentifier(x) do {:ok, v} = :"EST".decode(:OID, x) ; v end
def extension(x) do {:ok, v} = :"EST".encode(:Extension, x) ; v end
def basicConstraints() do {:ok, v} = :"PKIX1Implicit-2009".encode(:BasicConstraints, {:BasicConstraints, false, :asn1_NOVALUE}) ; v end
def keyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:KeyUsage, list) ; v end
def decodeKeyPurposeId(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyPurposeId, list) ; v end
def decodeKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:KeyUsage, list) ; v end
def extendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".encode(:ExtKeyUsageSyntax, list) ; v end
def decodeExtendedKeyUsage(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:ExtKeyUsageSyntax, list) ; v end
def decodePolicy(list) do {:ok, v} = :"PKIX1Implicit-2009".decode(:PolicyInformation, list) ; v end
def decodeQCS(list) do {:ok, v} = :KEP.decode(:QCStatement, list) ; v end
def start() do
children = [ { Bandit, scheme: :http, port: 8047, plug: __MODULE__ } ]
Supervisor.start_link(children, strategy: :one_for_one, name: CA.Supervisor)
end
# Authority PKI X.509 EST RFC 7030 3.2.2
get "/.well-known/est/ca" do CA.EST.Get.get(conn, [], "Authority", [], "CA") end
get "/.well-known/est/cacerts" do CA.EST.Get.get(conn, [], "Authority", [], "CMS") end
get "/.well-known/est/csrattrs" do CA.EST.Get.get(conn, [], "Authority", [], "ABAC") end
post "/.well-known/est/simpleenroll" do CA.EST.Post.post(conn, [], "Authority", [], "ENROLL") end
post "/.well-known/est/simplereenroll" do CA.EST.Post.post(conn, [], "Authority", [], "RE-ENROLL") end
post "/.well-known/est/serverkeygen" do CA.EST.Post.post(conn, [], "Authority", [], "KEYGEN") end
post "/.well-known/est/fullcmc" do CA.EST.Post.post(conn, [], "Authority", [], "CMC") end
# See Page 36 of RFC 7030
# [1] https://www.rfc-editor.org/rfc/rfc7030
# [2] https://www.ietf.org/archive/id/draft-ietf-lamps-rfc7030-csrattrs-07.html
def csrattributes() do
{:ok, bin} = :"EST".encode(:CsrAttrs, [
oid: CA.AT.oid(:"id-at-challengePassword"),
oid: CA.X962.oid(:"id-ds-ecdsa-with-SHA384"),
attribute: {:Attribute, CA.X962.oid(:"id-kt-ecPublicKey"), [objectIdentifier(CA.ALG.oid(:secp384r1))] },
attribute: {:Attribute, CA.AT.oid(:"id-at-rsaEncryption"), [integer(4096)]},
attribute: {:Attribute, CA.AT.oid(:"id-at-extensionRequest"), [
extension({:Extension, CA.CE.oid(:"id-ce-keyUsage"), true, keyUsage([:digitalSignature, :keyCertSign, :cRLSign])}),
extension({:Extension, CA.CE.oid(:"id-ce-basicConstraints"), true, basicConstraints()}),
extension({:Extension, CA.CE.oid(:"id-ce-extKeyUsage"), false,
extendedKeyUsage([ CA.KP.oid(:"id-kp-serverAuth"),
CA.KP.oid(:"id-kp-clientAuth"),
CA.KP.oid(:"id-kp-codeSigning"),
CA.KP.oid(:"id-kp-emailProtection") ])})
]}
])
bin
end
match _ do send_resp(conn, 404, "Please refer to https://authority.erp.uno for more information.\n") end
def encode(x) do
case Jason.encode(x) do
{:ok, bin} -> bin
{:error, _} -> ""
end |> Jason.Formatter.pretty_print
end
end