From 2ad01b17879e986aa9d3d5606cc08dea60f05992 Mon Sep 17 00:00:00 2001 From: sabiwara Date: Wed, 1 Nov 2023 09:00:37 +0900 Subject: [PATCH 1/3] Always use system certificates --- lib/mix/lib/mix/utils.ex | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index 7ec4311f3a3..4716b9fd703 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -655,23 +655,8 @@ defmodule Mix.Utils do headers = [{~c"user-agent", ~c"Mix/#{System.version()}"}] request = {:binary.bin_to_list(path), headers} - # Use the system certificates if available, otherwise skip peer verification - # TODO: Always use system certificates when OTP >= 25.1 is required - ssl_options = - if Code.ensure_loaded?(:httpc) and function_exported?(:httpc, :ssl_verify_host_options, 1) do - try do - apply(:httpc, :ssl_verify_host_options, [true]) - rescue - _ -> - Mix.shell().error( - "warning: failed to load system certificates. SSL peer verification will be skipped but downloads are still verified with a checksum" - ) - - [verify: :verify_none] - end - else - [verify: :verify_none] - end + # Use the system certificates + ssl_options = :httpc.ssl_verify_host_options(true) # We are using relaxed: true because some servers is returning a Location # header with relative paths, which does not follow the spec. This would From e6af52db85186aa7deb9b02737414405adc5d32c Mon Sep 17 00:00:00 2001 From: sabiwara Date: Wed, 1 Nov 2023 19:12:20 +0900 Subject: [PATCH 2/3] Inline :httpc.ssl_verify_host_options/1 for now --- lib/mix/lib/mix/utils.ex | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index 4716b9fd703..f0a8294912b 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -656,7 +656,14 @@ defmodule Mix.Utils do request = {:binary.bin_to_list(path), headers} # Use the system certificates - ssl_options = :httpc.ssl_verify_host_options(true) + # Currently we inline what `:httpc.ssl_verify_host_options/1` is doing, because it is not present + # on OTP < 25.1. + # TODO: just use `ssl_options = :httpc.ssl_verify_host_options(true)` once OTP >= 26.0 is required. + ssl_options = [ + verify: :verify_peer, + cacerts: :public_key.cacerts_get(), + customize_hostname_check: [match_fun: :public_key.pkix_verify_hostname_match_fun(:https)] + ] # We are using relaxed: true because some servers is returning a Location # header with relative paths, which does not follow the spec. This would From 1a8251d4f5dbf31845cf916a1691380f624d10a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 1 Nov 2023 11:34:35 +0100 Subject: [PATCH 3/3] Update lib/mix/lib/mix/utils.ex --- lib/mix/lib/mix/utils.ex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/mix/lib/mix/utils.ex b/lib/mix/lib/mix/utils.ex index f0a8294912b..e28a80245a9 100644 --- a/lib/mix/lib/mix/utils.ex +++ b/lib/mix/lib/mix/utils.ex @@ -656,9 +656,7 @@ defmodule Mix.Utils do request = {:binary.bin_to_list(path), headers} # Use the system certificates - # Currently we inline what `:httpc.ssl_verify_host_options/1` is doing, because it is not present - # on OTP < 25.1. - # TODO: just use `ssl_options = :httpc.ssl_verify_host_options(true)` once OTP >= 26.0 is required. + # TODO: use `ssl_options = :httpc.ssl_verify_host_options(true)` on Erlang/OTP 26+ ssl_options = [ verify: :verify_peer, cacerts: :public_key.cacerts_get(),