123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- -module(mad_ca).
- -include_lib("public_key/include/public_key.hrl").
- -compile(export_all).
- host() -> "ca.n2o.dev:8046".
- 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"}.
- rsa(X) -> cmd("rsa",X).
- ecc(X) -> cmd("ecc",X).
- cmd(C,[]) -> boot(C), {ok,C};
- cmd(C,["ca"]) -> boot(C), up(C), {ok,C};
- cmd(C,[T|N]) -> boot(C), enroll(C,T,N), {ok,C};
- cmd(C,_) -> boot(C), {ok,C}.
- boot(Crypto) ->
- {Dir,CNF} = root(Crypto),
- case file:read_file_info(Dir++CNF) of
- {ok,_} -> skip;
- {error,_} -> {Dir,CNF} = root(Crypto), filelib:ensure_dir(Dir),
- file:write_file(Dir++CNF,replace(replace(cnf(),"PATH",mad_utils:cwd()),"CRYPTO",Crypto)),
- up(Crypto) end, {ok,Crypto}.
- up(Crypto) ->
- application:start(inets),
- URI = cat(["http://",host(),"/up/",Crypto]),
- {ok,{{"HTTP/1.1",200,"OK"},_,Cert}} = httpc:request(post,{URI,[],[],<<"">>},[],[]),
- PEM = list_to_binary(Cert),
- ok = file:write_file(cat(["cert/",Crypto,"/caroot.pem"]),PEM),
- dump(PEM,"CA").
- enroll(Crypto,Type,Name) when (Type == "server" orelse Type == "client" orelse Type == "ocsp")
- andalso (Crypto == "rsa" orelse Crypto == "ecc") ->
- Pass = application:get_env(ca,passin,"pass:0"),
- application:start(inets),
- Y = string:join(Name," "),
- ok = key(Crypto,Pass,Y),
- {ok, F} = file:read_file(cat(["cert/",Crypto,"/",Y,".csr"])),
- URI = cat(["http://",host(),"/enroll/",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),
- dump(PEM,Y).
- dump(PEM,Y) ->
- {_,{_,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 KEY: ~p~n",[Y,PKIInfo]).
- key("rsa",_,X) ->
- {done,0,_} = sh:run("openssl genrsa -out \"cert/rsa/"++ X ++ ".key\" 2048"),
- {done,0,_} = 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 -out \"cert/ecc/"++X++".ecp\""),
- {done,0,_} = sh:run("cp \"cert/ecc/"++X++".ecp\" key"),
- {done,0,_} = 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,_} = sh:run("openssl ec -in \"cert/ecc/"++X++".key.enc\" -out \"cert/ecc/"++X++".key\" -passin "++Pass),
- ok.
- cnf() ->
- mad_repl:load(),
- try lists:flatten(
- [case string:str(File,"priv/cnf") of 1 -> Bin; _ -> []
- end || {File,Bin} <- ets:tab2list(filesystem), is_list(File)])
- catch _:_ -> [] end.
|