Namdak Tonpa 5 years ago
parent
commit
6a2fca1dbc
3 changed files with 60 additions and 76 deletions
  1. 1 1
      include/mad.hrl
  2. BIN
      mad
  3. 59 75
      src/mad_ca.erl

+ 1 - 1
include/mad.hrl

@@ -1 +1 @@
--define(VERSION,"6.8.0-6-g76fe77d").
+-define(VERSION,"6.8.0-7-g6c9652b").

BIN
mad


+ 59 - 75
src/mad_ca.erl

@@ -1,96 +1,80 @@
 -module(mad_ca).
 -include_lib("public_key/include/public_key.hrl").
--copyright("SYNRC Certificate Authority").
 -compile(export_all).
 
-write(Gen,Bin) -> io:format("Generated: ~p~n",[Gen]), file:write_file(Gen,Bin).
-replace(S,A,B) -> re:replace(S,A,B,[global,{return,list}]).
-u(X) -> string:to_upper(X).
+cat(X)         -> lists:concat(X).
+replace(S,A,B) -> re:replace(S,A,B,[global,{return,binary}]).
+u(X)           -> string:to_upper(X).
+root(Crypto)   -> {cat(["cert/",Crypto,"/"]),"synrc.cnf"}.
 
-boot(Crypto) ->
-   Temp    = template(),
-   Tem2    = replace(Temp,"PATH", mad_utils:cwd()),
-   Bin     = iolist_to_binary(replace(Tem2,"CRYPTO",Crypto)),
-   Gen     = lists:concat(["cert/",Crypto,"/synrc.cnf"]),
-   Index   = lists:concat(["cert/",Crypto,"/index.txt"]),
-   CRL     = lists:concat(["cert/",Crypto,"/crlnumber"]),
-   Serial  = lists:concat(["cert/",Crypto,"/serial"]),
-   Counter = <<"1000">>,
-   case file:read_file_info(Gen) of
-         {error,_} ->
-             filelib:ensure_dir(Gen),
-             lists:map(fun({A,B}) -> file:write_file(A,B) end,
-                [{Index,<<>>},{CRL,Counter},{Serial,Counter},{Gen,Bin}]),
-             ca(Crypto);
-         {ok,_} -> skip end,
-   {ok,man}.
-
-subj() -> io:format("Subject not specified.").
+rsa(X)         -> cmd("rsa",X).
+ecc(X)         -> cmd("ecc",X).
 
-rsa(["ca"]) -> boot("rsa"), ca("rsa"), {ok,rsa};
-rsa([Type|Name]) ->  boot("rsa"), enroll("rsa",Type,Name);
-rsa(_) -> boot("rsa").
+cmd(C,[])      -> {ok, C};
+cmd(C,["ca"])  -> boot(C), ca(C), {ok,C};
+cmd(C,[T|N])   -> boot(C), enroll(C,T,N), {ok,C};
+cmd(C,_)       -> boot(C), {ok,C}.
 
-ecc(["ca"]) -> boot("ecc"), ca("ecc"), {ok,ecc};
-ecc([Type|Name]) ->  boot("ecc"), enroll("ecc",Type,Name);
-ecc(_) -> boot("ecc").
+boot(Crypto) ->
+    {Dir,CNF} = root(Crypto),
+    case file:read_file_info(Dir++CNF) of
+        {error,_} -> do_boot(Crypto);
+        {ok,_} -> skip end, {ok,Crypto}.
 
+do_boot(Crypto) ->
+    {Num,Bin} = {<<"1000">>,replace(replace(cnf(),"PATH",mad_utils:cwd()),"CRYPTO",Crypto)},
+    {Dir,CNF} = root(Crypto), filelib:ensure_dir(Dir),
+    Files     = [{"index.txt",<<>>},{"crlnumber",Num},{"serial",Num},{CNF,Bin}],
+    lists:map(fun({A,B}) -> file:write_file(Dir++A,B) end, Files), ca(Crypto).
 
 ca("rsa") ->
-  {done,0,Bin}  = sh:run("openssl genrsa -out cert/rsa/caroot.key 2048"),
-  {done,0,Bin2} = sh:run("openssl req -new -x509 -days 3650 -config cert/rsa/synrc.cnf"
-                         " -key cert/rsa/caroot.key -out cert/rsa/caroot.pem"
-                         " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN=CA\"");
+    {done,0,_} = sh:run("openssl genrsa -out cert/rsa/caroot.key 2048"),
+    {done,0,_} = sh:run("openssl req -new -x509 -days 3650 -config cert/rsa/synrc.cnf"
+       " -key cert/rsa/caroot.key -out cert/rsa/caroot.pem"
+       " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN=CA\"");
+
 ca("ecc") ->
-  Pass = application:get_env(ca,passin,"pass:0"),
-  {done,0,Bin} = sh:run("openssl ecparam -genkey -name secp384r1"),
-  file:write_file("cert/ecc/ca.key",Bin),
-  {done,0,Bin2} = sh:run("openssl ec -aes256 -in cert/ecc/ca.key"
-                         " -out cert/ecc/caroot.key -passout " ++ Pass),
-  {done,0,Bin3} = sh:run("openssl req -config cert/ecc/synrc.cnf -days 3650 -new -x509"
-                         " -key cert/ecc/caroot.key -out cert/ecc/caroot.pem -passin " ++ Pass ++
-                         " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN=CA\""),
-  ok.
+    Pass = application:get_env(ca,passin,"pass:0"),
+    {done,0,_} = sh:run("openssl ecparam -genkey -name secp384r1 -out cert/ecc/ca.key"),
+    {done,0,_} = sh:run("openssl ec -aes256 -in cert/ecc/ca.key -out cert/ecc/caroot.key -passout " ++ Pass),
+    {done,0,_} = sh:run("openssl req -config cert/ecc/synrc.cnf -days 3650 -new -x509"
+        " -key cert/ecc/caroot.key -out cert/ecc/caroot.pem -passin " ++ Pass ++
+        " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN=CA\"").
 
 enroll(Crypto,Type,Name) when (Type == "server" orelse Type == "client")
                       andalso (Crypto == "rsa" orelse Crypto == "ecc") ->
-  Pass = application:get_env(ca,passin,"pass:0"),
-  application:start(inets),
-  X = string:join(Name,"\\ "),
-  Y = string:join(Name," "),
-  key(Crypto,Pass,X),
-  {ok, F} = file:read_file("cert/"++Crypto++"/"++Y++".csr"),
-  {ok,{{"HTTP/1.1",200,"OK"},_,Cert}}
-    = httpc:request(post,{"http://ca.n2o.dev:8046/"++Crypto++"/"++Type,
-                       [],"multipart/form-data",F},[],[]),
-  DER = list_to_binary(Cert),
-  file:write_file("cert/"++Crypto++"/"++Y++".pem",DER),
-  Entries = public_key:pem_decode(DER),
-  {value, CertEntry} = lists:keysearch('Certificate', 1, Entries),
-  {_, DerCert, _} = CertEntry,
-  Decoded = public_key:pkix_decode_cert(DerCert, otp),
-  PK = Decoded#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo,
-  io:format("CERT: ~s ~s '~s'~nKEY: ~p~n",[u(Crypto),u(Type),X,PK]),
-  {ok,rsa}.
-
+    Pass = application:get_env(ca,passin,"pass:0"),
+    application:start(inets),
+    X   = string:join(Name,"\\ "),
+    Y   = string:join(Name," "),
+    ok  = key(Crypto,Pass,Y),
+    {ok, F} = file:read_file(cat(["cert/",Crypto,"/",Y,".csr"])),
+    URI = cat(["http://ca.n2o.dev:8046/",Crypto,"/",Type]),
+    {ok,{{"HTTP/1.1",200,"OK"},_,Cert}} = httpc:request(post,{URI,[],"multipart/form-data",F},[],[]),
+    PEM = list_to_binary(Cert),
+    ok  = file:write_file(cat(["cert/",Crypto,"/",Y,".pem"]),PEM),
+    {_,{_,D,_}} = lists:keysearch('Certificate',1,public_key:pem_decode(PEM)),
+    OTPCert = public_key:pkix_decode_cert(D,otp),
+    PKIInfo = OTPCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subjectPublicKeyInfo,
+    io:format("CERT: ~s ~s '~s'~nKEY: ~p~n",[u(Crypto),u(Type),Y,PKIInfo]).
 
 key("rsa",_,X) ->
-  {done,0,Bin}  = sh:run("openssl genrsa -out cert/rsa/"++ X ++ ".key 2048"),
-  {done,0,Bin2} = sh:run("openssl req -new -days 365 -key cert/rsa/"++ X ++".key"
-                         " -out cert/rsa/"++ X ++".csr "
-                         " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN="++ X ++ "\""), ok;
+    {done,0,Bin}  = sh:run("openssl genrsa -out \"cert/rsa/"++ X ++ ".key\" 2048"),
+    {done,0,Bin2} = sh:run("openssl req -new -days 365 -key \"cert/rsa/"++ X ++".key\" -out \"cert/rsa/"++ X ++".csr\" "
+        " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN="++ X ++ "\""), ok;
+
 key("ecc",Pass,X) ->
-  Pass = application:get_env(ca,passin,"pass:0"),
-  {done,0,_}   = sh:run("openssl ecparam -name secp384r1 > cert/ecc/"++X++".ecp"),
-  {done,0,_}   = sh:run("cp cert/ecc/"++X++".ecp key"),
-  {done,0,Bin} = sh:run("openssl req -config cert/ecc/synrc.cnf -passout " ++ Pass ++
-                        " -new -newkey ec:key"
-                        " -keyout cert/ecc/"++X++".key.enc -out cert/ecc/"++X++".csr"
-                        " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN="++X++"\""),
-  {done,0,Bin2} = sh:run("openssl ec -in cert/ecc/"++X++".key.enc -out cert/ecc/server.key -passin "++Pass),
-  ok.
+    Pass = application:get_env(ca,passin,"pass:0"),
+    {done,0,_}   = sh:run("openssl ecparam -name secp384r1 -out \"cert/ecc/"++X++".ecp\""),
+    {done,0,_}   = sh:run("cp \"cert/ecc/"++X++".ecp\" key"),
+    {done,0,Bin} = sh:run("openssl req -config cert/ecc/synrc.cnf -passout " ++ Pass ++
+        " -new -newkey ec:key -keyout \"cert/ecc/"++X++".key.enc\" -out \"cert/ecc/"++X++".csr\""
+        " -subj \"/C=UA/ST=Kyiv/O=SYNRC/CN="++X++"\""),
+    {done,0,_}    = sh:run("rm key"),
+    {done,0,Bin2} = sh:run("openssl ec -in \"cert/ecc/"++X++".key.enc\" -out \"cert/ecc/"++X++".key\" -passin "++Pass),
+    ok.
 
-template() ->
+cnf() ->
     mad_repl:load(),
     try lists:flatten(
         [case string:str(File,"priv/cnf") of 1 -> Bin; _ -> []