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
Current section
Files
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.