瀏覽代碼

add ssl cert validation, unless OTP version is too old

pull/624/head
Tristan Sloughter 9 年之前
父節點
當前提交
3485f08a03
共有 5 個檔案被更改,包括 3932 行新增1 行删除
  1. +1
    -0
      rebar.config
  2. +1
    -0
      rebar.lock
  3. +1
    -0
      src/rebar.app.src
  4. +3868
    -0
      src/rebar_cacerts.erl
  5. +61
    -1
      src/rebar_pkg_resource.erl

+ 1
- 0
rebar.config 查看文件

@ -2,6 +2,7 @@
%% ex: ts=4 sw=4 ft=erlang et
{deps, [{erlware_commons, "0.13.0"},
{ssl_verify_hostname, "1.0.5"},
{providers, "1.4.1"},
{getopt, "0.8.2"},
{bbmustache, "1.0.3"},

+ 1
- 0
rebar.lock 查看文件

@ -2,4 +2,5 @@
{<<"providers">>,{pkg,<<"providers">>,<<"1.4.1">>},0},
{<<"erlware_commons">>,{pkg,<<"erlware_commons">>,<<"0.13.0">>},0},
{<<"relx">>,{pkg,<<"relx">>,<<"3.3.0">>},0},
{<<"ssl_verify_hostname">>,{pkg,<<"ssl_verify_hostname">>,<<"1.0.5">>},0},
{<<"getopt">>,{pkg,<<"getopt">>,<<"0.8.2">>},0}].

+ 1
- 0
src/rebar.app.src 查看文件

@ -18,6 +18,7 @@
erlware_commons,
providers,
bbmustache,
ssl_verify_hostname,
relx,
inets]},
{env, [

+ 3868
- 0
src/rebar_cacerts.erl
文件差異過大導致無法顯示
查看文件


+ 61
- 1
src/rebar_pkg_resource.erl 查看文件

@ -10,6 +10,7 @@
,make_vsn/1]).
-include("rebar.hrl").
-include_lib("public_key/include/OTP-PUB-KEY.hrl").
lock(_AppDir, Source) ->
Source.
@ -94,7 +95,7 @@ make_vsn(_) ->
request(Url, ETag) ->
case httpc:request(get, {Url, [{"if-none-match", ETag} || ETag =/= false]},
[{relaxed, true}],
[{ssl, [ssl_opts(Url)]}, {relaxed, true}],
[{body_format, binary}],
rebar) of
{ok, {{_Version, 200, _Reason}, Headers, Body}} ->
@ -120,3 +121,62 @@ etag(Path) ->
{error, _} ->
false
end.
ssl_opts(Url) ->
case check_ssl_version() of
true ->
{ok, {_, _, Hostname, _, _, _}} = http_uri:parse(ec_cnv:to_list(Url)),
VerifyFun = {fun ssl_verify_hostname:verify_fun/3, [{check_hostname, Hostname}]},
CACerts = cacerts(),
[{verify, verify_peer}, {depth, 2}, {cacerts, CACerts}
,{partial_chain, fun partial_chain/1}, {verify_fun, VerifyFun}];
false ->
?WARN("Insecure HTTPS request (peer verification disabled), please update to OTP 17.4 or later", []),
[{verify, verify_none}]
end.
partial_chain(Certs) ->
Certs1 = [{Cert, public_key:pkix_decode_cert(Cert, otp)} || Cert <- Certs],
CACerts = cacerts(),
CACerts1 = [public_key:pkix_decode_cert(Cert, otp) || Cert <- CACerts],
case ec_lists:find(fun({_, Cert}) ->
check_cert(CACerts1, Cert)
end, Certs1) of
{ok, Trusted} ->
{trusted_ca, element(1, Trusted)};
_ ->
unknown_ca
end.
extract_public_key_info(Cert) ->
((Cert#'OTPCertificate'.tbsCertificate)#'OTPTBSCertificate'.subjectPublicKeyInfo).
cacerts() ->
Pems = public_key:pem_decode(rebar_cacerts:cacerts()),
[Der || {'Certificate', Der, _} <- Pems].
check_cert(CACerts, Cert) ->
lists:any(fun(CACert) ->
extract_public_key_info(CACert) == extract_public_key_info(Cert)
end, CACerts).
check_ssl_version() ->
case application:get_key(ssl, vsn) of
{ok, Vsn} ->
parse_vsn(Vsn) >= {5, 3, 6};
_ ->
false
end.
parse_vsn(Vsn) ->
version_pad(string:tokens(Vsn, ".")).
version_pad([Major]) ->
{list_to_integer(Major), 0, 0};
version_pad([Major, Minor]) ->
{list_to_integer(Major), list_to_integer(Minor), 0};
version_pad([Major, Minor, Patch]) ->
{list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)};
version_pad([Major, Minor, Patch | _]) ->
{list_to_integer(Major), list_to_integer(Minor), list_to_integer(Patch)}.

Loading…
取消
儲存