Packages

otpbp

6.3.2
7.19.2 7.18.0 7.16.1 7.15.0 7.14.0 7.13.0 7.12.0 7.11.0 7.10.2 7.9.3 7.9.2 7.9.1 7.8.7 7.8.6 7.8.5 7.8.4 7.7.1 7.7.0 7.6.3 7.6.2 7.6.1 7.6.0 7.5.1 7.5.0 7.4.0 7.3.4 7.3.3 7.3.2 7.3.1 7.3.0 7.2.0 7.1.1 7.1.0 7.0.4 7.0.3 7.0.2 7.0.1 6.27.0 6.26.2 6.26.1 6.26.0 6.25.0 6.24.0 6.23.0 6.22.2 6.21.3 6.21.2 6.21.1 6.20.2 6.19.1 6.19.0 6.18.3 6.18.2 6.18.1 6.18.0 6.17.1 6.17.0 6.16.0 6.15.4 6.15.3 6.15.2 6.15.1 6.15.0 6.14.0 6.13.5 6.13.4 6.13.3 6.13.2 6.13.1 6.13.0 6.12.0 6.11.2 6.11.1 6.10.0 6.9.2 6.9.1 6.9.0 6.8.0 6.7.1 6.7.0 6.6.4 6.6.3 6.6.2 6.6.1 6.6.0 6.5.0 6.4.0 6.3.3 6.3.2 6.3.1 6.3.0 6.2.1 6.2.0 6.1.0 6.0.0 5.40.0 5.39.1 5.39.0 5.38.0 5.37.0 5.36.0 5.35.2 5.34.3 5.34.2 5.34.1 5.33.1 5.32.1 5.32.0 5.31.3 5.31.2 5.31.1 5.31.0 5.30.1 5.30.0 5.29.0 5.28.4 5.28.3 5.28.2 5.28.1 5.28.0 5.27.0 5.26.5 5.26.4 5.26.3 5.26.2 5.26.1 5.26.0 5.25.0 5.24.2 5.24.1 5.23.0 5.22.2 5.22.1 5.22.0 5.21.0 5.20.1 5.20.0 5.19.4 5.19.3 5.19.2 5.19.1 5.19.0 5.18.0 5.17.0 5.16.3 5.16.1 5.16.0 5.15.1 5.15.0 5.14.0 5.13.1 5.13.0 5.12.1 5.12.0 5.11.2 5.11.1 5.10.1 5.10.0 5.9.0 5.8.0 5.7.0 5.6.1 5.6.0 5.5.0 5.4.2 5.4.1 5.4.0 5.3.0 5.2.2 5.2.1 5.2.0 5.1.2 5.1.1 4.80.0 4.79.1 4.79.0 4.78.0 4.77.0 4.76.2 4.75.3 4.75.2 4.75.1 4.74.0 4.73.1 4.73.0 4.72.3 4.72.2 4.72.1 4.72.0 4.71.1 4.71.0 4.70.0 4.69.4 4.69.3 4.69.2 4.69.1 4.69.0 4.68.0 4.67.5 4.67.4 4.67.3 4.67.2 4.67.0 4.66.0 4.65.2 4.65.1 4.64.0 4.63.2 4.63.1 4.63.0 4.62.0 4.61.1 4.61.0 4.60.4 4.60.3 4.60.2 4.60.1 4.60.0 4.59.0 4.58.0 4.57.2 4.57.1 4.57.0 4.56.2 4.56.1 4.56.0 4.55.0 4.54.0 4.53.0 4.52.1 4.52.0 4.51.3 4.51.2 4.51.0 4.50.0 4.49.3 4.49.2

OTP backports

Current section

Files

Jump to
otpbp src otpbp_pubkey_os_cacerts.erl
Raw

src/otpbp_pubkey_os_cacerts.erl

-module(otpbp_pubkey_os_cacerts).
-compile({parse_transform, otpbp_pt}).
-include_lib("public_key/include/public_key.hrl").
-include_lib("kernel/include/file.hrl").
-ifndef(HAVE_pubkey_os_cacerts__clear_0).
% OTP 25.0
-export([clear/0]).
-endif.
-ifndef(HAVE_pubkey_os_cacerts__format_error_2).
% OTP 27.0
-export([format_error/2]).
-endif.
-ifndef(HAVE_pubkey_os_cacerts__get_0).
% OTP 25.0
-export([get/0]).
-endif.
-ifndef(HAVE_pubkey_os_cacerts__load_0).
% OTP 25.0
-export([load/0]).
-endif.
-ifndef(HAVE_pubkey_os_cacerts__load_1).
% OTP 25.0
-export([load/1]).
-endif.
-ifndef(HAVE_pubkey_os_cacerts__get_0).
-ifdef(HAVE_pubkey_os_cacerts__load_0).
-import(pubkey_os_cacerts, [load/0]).
-endif.
-endif.
-ifndef(HAVE_erlang__get_cookie_1).
-ifndef(HAVE_erlang__set_cookie_1).
-ifndef(HAVE_inet__gen_udp_module_1).
-record(cert, {der :: public_key:der_encoded(), otp :: #'OTPCertificate'{}}).
-endif.
-endif.
-endif.
-ifndef(HAVE_pubkey_os_cacerts__clear_0).
-ifdef(HAVE_persistent_term__erase_1).
clear() -> persistent_term:erase(pubkey_os_cacerts).
-else.
clear() -> erase(pubkey_os_cacerts) =/= udefined.
-endif.
-endif.
-ifndef(HAVE_pubkey_os_cacerts__format_error_2).
format_error(Reason, [{_M, _F, _As, Info} | _]) ->
#{general => io_lib:format("Failed to load cacerts: ~s",
[case proplists:get_value(error_info, Info) of
#{cause := enoent} -> "operating system CA bundle could not be located";
#{cause := {enotsup, OS}} ->
io_lib:format("operating system ~p is not supported", [OS]);
#{cause := {eopnotsupp, SubReason}} ->
io_lib:format("operation failed because of ~p", [SubReason]);
#{cause := {eopnotsupp, Status, _Acc}} ->
io_lib:format("operation failed with status ~B", [Status])
end]),
reason => io_lib:format("~p: ~p", [pubkey_os_cacerts, Reason])}.
-endif.
-ifndef(HAVE_pubkey_os_cacerts__get_0).
get() ->
case get2() of
undefined ->
case load() of
ok -> get1();
{error, Reason} ->
erlang:error({failed_load_cacerts, conv_error_reason(Reason)},
none,
[{error_info, #{cause => Reason, module => pubkey_os_cacerts}}])
end;
CaCerts -> CaCerts
end.
-compile({inline, [get1/0]}).
-ifdef(HAVE_persistent_term__get_1).
get1() -> persistent_term:get(pubkey_os_cacerts).
-else.
get1() ->
Value = get(pubkey_os_cacerts),
Value =:= undefined andalso error(badarg),
Value.
-endif.
-compile({inline, [get2/0]}).
-ifdef(HAVE_persistent_term__get_2).
get2() -> persistent_term:get(pubkey_os_cacerts, undefined).
-else.
get2() -> get(pubkey_os_cacerts).
-endif.
-compile({inline, conv_error_reason/1}).
conv_error_reason(enoent) -> enoent;
conv_error_reason({enotsup, _OS}) -> enotsup;
conv_error_reason({eopnotsupp, _Reason}) -> eopnotsupp;
conv_error_reason({eopnotsupp, _Status, _Acc}) -> eopnotsupp.
-endif.
-ifndef(HAVE_pubkey_os_cacerts__load_1).
load(Paths) -> load(Paths, {error, enoent}).
-ifndef(NEED_load_2).
-define(NEED_load_2, true).
-endif.
-endif.
-ifndef(HAVE_pubkey_os_cacerts__load_0).
load() ->
case os:type() of
{unix, darwin} -> load_darwin();
{unix, OS} ->
load(if
OS =:= linux -> linux_paths();
OS =:= freebsd; OS =:= openbsd; OS =:= netbsd -> bsd_paths();
OS =:= sunos -> sunos_paths()
end,
undefined);
OS -> {error, {enotsup, OS}}
end.
-compile({inline, load_darwin/0}).
load_darwin() ->
try run_cmd("/usr/bin/security",
["export",
"-t", "certs",
"-f", "pemseq",
"-k", "/System/Library/Keychains/SystemRootCertificates.keychain"]) of
{ok, Bin} -> decode_result(Bin);
Err -> Err
catch
error:Reason -> {error, {eopnotsupp, Reason}}
end.
-compile({inline, linux_paths/0}).
linux_paths() ->
["/etc/ssl/certs/ca-certificates.crt", %% Debian, Ubuntu, Gentoo
"/etc/pki/tls/certs/ca-bundle.crt", %% Fedora, RHEL 6, Amazon Linux
"/etc/ssl/ca-bundle.pem", %% OpenSUSE
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", %% CentOS, RHEL 7
"/etc/ssl/cert.pem"]. %% Alpine Linux
-compile({inline, bsd_paths/0}).
bsd_paths() ->
["/etc/ssl/cert.pem",
"/etc/openssl/certs/cacert.pem", %% netbsd (if installed)
"/etc/openssl/certs/ca-certificates.crt",
"/usr/local/share/certs/ca-root-nss.crt"].
-compile({inline, sunos_paths/0}).
sunos_paths() ->
["/etc/certs/CA/", %% Oracle Solaris, some older illumos distros
"/etc/ssl/cacert.pem"]. %% OmniOS
-compile({inline, run_cmd/2}).
run_cmd(Cmd, Args) ->
Port = open_port({spawn_executable, Cmd}, [{args, Args}, binary, exit_status, stderr_to_stdout]),
unlink(Port),
cmd_data(Port, <<>>).
cmd_data(Port, Acc) ->
receive
{Port, {data, Bin}} -> cmd_data(Port, <<Acc/binary, Bin/binary>>);
{Port, {exit_status, 0}} -> {ok, Acc};
{Port, {exit_status, Status}} -> {error, {eopnotsupp, Status, Acc}}
end.
-ifndef(NEED_load_2).
-define(NEED_load_2, true).
-endif.
-endif.
-ifdef(NEED_load_2).
load([Path|Paths], Error) ->
case dir_or_file(Path) of
enoent -> load(Paths, Error);
directory ->
case load_from_files(Path) of
ok -> ok;
Err -> load(Paths, Err)
end;
file ->
case load_from_file(Path) of
ok -> ok;
Err -> load(Paths, Err)
end
end;
load([], Error) -> Error.
-compile({inline, dir_or_file/1}).
dir_or_file(Path) ->
case file:read_file_info(Path) of
{ok, #file_info{type = directory}} -> directory;
{ok, #file_info{type = regular}} -> file;
{ok, #file_info{}} -> %% Link
case filelib:is_dir(Path) of
true -> directory;
false -> file
end;
{error, _} -> enoent
end.
-compile({inline, load_from_file/1}).
load_from_file(Path) when is_list(Path); is_binary(Path) ->
try
{ok, Binary} = file:read_file(Path),
ok = decode_result(Binary)
catch
_:_Reason -> {error, enoent}
end.
-compile({inline, load_from_files/1}).
load_from_files(Path) ->
store(filelib:fold_files(Path, ".*\.pem", false,
fun(FileName, Acc) ->
try
{ok, Bin} = file:read_file(FileName),
lists:foldr(fun({'Certificate', Der, not_encrypted}, A) ->
[#cert{der = Der, otp = public_key:pkix_decode_cert(Der, otp)}|A];
(_, A) -> A
end,
Acc, pubkey_pem:decode(Bin))
catch
_:_ -> Acc
end
end,
[])).
-ifndef(NEED_decode_result_1).
-define(NEED_decode_result_1, true).
-endif.
-ifndef(NEED_store_1).
-define(NEED_store_1, true).
-endif.
-endif.
-ifdef(NEED_decode_result_1).
decode_result(Binary) ->
MakeCert = fun({'Certificate', Der, not_encrypted}, Acc) ->
try public_key:pkix_decode_cert(Der, otp) of
Decoded -> [#cert{der = Der, otp = Decoded}|Acc]
catch
_:_ -> Acc
end
end,
try
store(lists:foldl(MakeCert, [], pubkey_pem:decode(Binary)))
catch
_:Reason -> {error, Reason}
end.
-ifndef(NEED_store_1).
-define(NEED_store_1, true).
-endif.
-endif.
-ifdef(NEED_store_1).
store([]) -> {error, no_cacerts_found};
store(CaCerts) -> put(CaCerts).
-compile({inline, put/1}).
-ifdef(HAVE_persistent_term__put_2).
put(Value) -> persistent_term:put(pubkey_os_cacerts, Value).
-else.
put(Value) ->
put(pubkey_os_cacerts, Value),
ok.
-endif.
-endif.