diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh
index 3be0d36d88..839d057546 100644
--- a/Library/Homebrew/brew.sh
+++ b/Library/Homebrew/brew.sh
@@ -429,6 +429,20 @@ then
printf "\\n" >&2
fi
+ # Versions before Sierra don't handle custom cert files correctly, so need a full brewed curl.
+ if [[ "${HOMEBREW_MACOS_VERSION_NUMERIC}" -lt "101200" ]]
+ then
+ HOMEBREW_SYSTEM_CURL_TOO_OLD="1"
+ HOMEBREW_FORCE_BREWED_CURL="1"
+ fi
+
+ # The system libressl has a bug before macOS 10.15.6 where it incorrectly handles expired roots.
+ if [[ -z "${HOMEBREW_SYSTEM_CURL_TOO_OLD}" && "${HOMEBREW_MACOS_VERSION_NUMERIC}" -lt "101506" ]]
+ then
+ HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD="1"
+ HOMEBREW_FORCE_BREWED_CA_CERTIFICATES="1"
+ fi
+
# The system Git on macOS versions before Sierra is too old for some Homebrew functionality we rely on.
HOMEBREW_MINIMUM_GIT_VERSION="2.14.3"
if [[ "${HOMEBREW_MACOS_VERSION_NUMERIC}" -lt "101200" ]]
@@ -530,6 +544,12 @@ Your Git executable: $(unset git && type -p ${HOMEBREW_GIT})"
fi
fi
+if [[ -n "${HOMEBREW_FORCE_BREWED_CA_CERTIFICATES}" && -f "${HOMEBREW_PREFIX}/etc/ca-certificates/cert.pem" ]]
+then
+ export SSL_CERT_FILE="${HOMEBREW_PREFIX}/etc/ca-certificates/cert.pem"
+ export GIT_SSL_CAINFO="${HOMEBREW_PREFIX}/etc/ca-certificates/cert.pem"
+fi
+
# A bug in the auto-update process prior to 3.1.2 means $HOMEBREW_BOTTLE_DOMAIN
# could be passed down with the default domain.
# This is problematic as this is will be the old bottle domain.
@@ -567,6 +587,7 @@ export HOMEBREW_DEFAULT_TEMP
export HOMEBREW_TEMP
export HOMEBREW_CELLAR
export HOMEBREW_SYSTEM
+export HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD
export HOMEBREW_CURL
export HOMEBREW_CURL_WARNING
export HOMEBREW_SYSTEM_CURL_TOO_OLD
diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh
index 8d496d1220..57206086d5 100644
--- a/Library/Homebrew/cmd/update.sh
+++ b/Library/Homebrew/cmd/update.sh
@@ -375,11 +375,21 @@ user account:
EOS
fi
+ # we may want to use Homebrew CA certificates
+ if [[ -n "${HOMEBREW_FORCE_BREWED_CA_CERTIFICATES}" && ! -f "${HOMEBREW_PREFIX}/etc/ca-certificates/cert.pem" ]]
+ then
+ # we cannot install Homebrew CA certificates if homebrew/core is unavailable.
+ if [[ -d "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core" || -n "${HOMEBREW_INSTALL_FROM_API}" ]]
+ then
+ brew install ca-certificates || true
+ fi
+ fi
+
# we may want to use a Homebrew curl
if [[ -n "${HOMEBREW_FORCE_BREWED_CURL}" && ! -x "${HOMEBREW_PREFIX}/opt/curl/bin/curl" ]]
then
# we cannot install a Homebrew cURL if homebrew/core is unavailable.
- if [[ ! -d "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core" ]] || ! brew install curl
+ if [[ ! -d "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core" && -z "${HOMEBREW_INSTALL_FROM_API}" ]] || ! brew install curl
then
odie "'curl' must be installed and in your PATH!"
fi
@@ -389,7 +399,7 @@ EOS
[[ -n "${HOMEBREW_FORCE_BREWED_GIT}" && ! -x "${HOMEBREW_PREFIX}/opt/git/bin/git" ]]
then
# we cannot install a Homebrew Git if homebrew/core is unavailable.
- if [[ ! -d "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core" ]] || ! brew install git
+ if [[ ! -d "${HOMEBREW_LIBRARY}/Taps/homebrew/homebrew-core" && -z "${HOMEBREW_INSTALL_FROM_API}" ]] || ! brew install git
then
odie "'git' must be installed and in your PATH!"
fi
diff --git a/Library/Homebrew/development_tools.rb b/Library/Homebrew/development_tools.rb
index 89fd30e568..2d3ab61043 100644
--- a/Library/Homebrew/development_tools.rb
+++ b/Library/Homebrew/development_tools.rb
@@ -98,6 +98,11 @@ class DevelopmentTools
@non_apple_gcc_version = {}
end
+ sig { returns(T::Boolean) }
+ def ca_file_handles_most_https_certificates?
+ true
+ end
+
sig { returns(T::Boolean) }
def curl_handles_most_https_certificates?
true
diff --git a/Library/Homebrew/env_config.rb b/Library/Homebrew/env_config.rb
index 26ef31b11a..f75e3eeace 100644
--- a/Library/Homebrew/env_config.rb
+++ b/Library/Homebrew/env_config.rb
@@ -138,6 +138,11 @@ module Homebrew
description: "A space-separated list of licenses. Homebrew will refuse to install a " \
"formula if it or any of its dependencies has a license on this list.",
},
+ HOMEBREW_FORCE_BREWED_CA_CERTIFICATES: {
+ description: "If set, always use a Homebrew-installed `ca-certificates` rather than the system version. " \
+ "Automatically set if the system version is too old.",
+ boolean: true,
+ },
HOMEBREW_FORCE_BREWED_CURL: {
description: "If set, always use a Homebrew-installed `curl`(1) rather than the system version. " \
"Automatically set if the system version of `curl` is too old.",
diff --git a/Library/Homebrew/extend/os/mac/development_tools.rb b/Library/Homebrew/extend/os/mac/development_tools.rb
index 353ae30428..f7c49645c1 100644
--- a/Library/Homebrew/extend/os/mac/development_tools.rb
+++ b/Library/Homebrew/extend/os/mac/development_tools.rb
@@ -10,7 +10,7 @@ class DevelopmentTools
alias generic_locate locate
undef installed?, default_compiler, curl_handles_most_https_certificates?,
- subversion_handles_most_https_certificates?
+ ca_file_handles_most_https_certificates?, subversion_handles_most_https_certificates?
sig { params(tool: String).returns(T.nilable(Pathname)) }
def locate(tool)
@@ -37,6 +37,13 @@ class DevelopmentTools
:clang
end
+ sig { returns(T::Boolean) }
+ def ca_file_handles_most_https_certificates?
+ # The system CA file is too old for some modern HTTPS certificates on
+ # older macOS versions.
+ ENV["HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD"].nil?
+ end
+
sig { returns(T::Boolean) }
def curl_handles_most_https_certificates?
# The system Curl is too old for some modern HTTPS certificates on
diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb
index dc4975b617..0fbee44fca 100644
--- a/Library/Homebrew/formula_installer.rb
+++ b/Library/Homebrew/formula_installer.rb
@@ -796,6 +796,12 @@ class FormulaInstaller
# let's reset Utils::Git.available? if we just installed git
Utils::Git.clear_available_cache if formula.name == "git"
+ # use installed ca-certificates when it's needed and available
+ if formula.name == "ca-certificates" &&
+ !DevelopmentTools.ca_file_handles_most_https_certificates?
+ ENV["SSL_CERT_FILE"] = ENV["GIT_SSL_CAINFO"] = formula.pkgetc/"cert.pem"
+ end
+
# use installed curl when it's needed and available
if formula.name == "curl" &&
!DevelopmentTools.curl_handles_most_https_certificates?
diff --git a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi
index 2f3ce5b65d..c2568cc90c 100644
--- a/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi
+++ b/Library/Homebrew/sorbet/rbi/hidden-definitions/hidden.rbi
@@ -4626,6 +4626,8 @@ module Homebrew::EnvConfig
def self.forbidden_licenses(); end
+ def self.force_brewed_ca_certificates?(); end
+
def self.force_brewed_curl?(); end
def self.force_brewed_git?(); end
diff --git a/Library/Homebrew/utils/curl.rb b/Library/Homebrew/utils/curl.rb
index 6d3049d5d3..6d5ffdbf01 100644
--- a/Library/Homebrew/utils/curl.rb
+++ b/Library/Homebrew/utils/curl.rb
@@ -107,11 +107,9 @@ module Utils
verbose: verbose,
}.compact
- # SSL_CERT_FILE can be incorrectly set by users or portable-ruby and screw
- # with SSL downloads so unset it here.
result = system_command curl_executable(use_homebrew_curl: use_homebrew_curl),
args: curl_args(*args, **options),
- env: { "SSL_CERT_FILE" => nil }.merge(env),
+ env: env,
timeout: end_time&.remaining,
**command_options
diff --git a/docs/Manpage.md b/docs/Manpage.md
index f539da429f..e56fd566b7 100644
--- a/docs/Manpage.md
+++ b/docs/Manpage.md
@@ -1976,6 +1976,9 @@ example, run `export HOMEBREW_NO_INSECURE_REDIRECT=1` rather than just
- `HOMEBREW_FORBIDDEN_LICENSES`
A space-separated list of licenses. Homebrew will refuse to install a formula if it or any of its dependencies has a license on this list.
+- `HOMEBREW_FORCE_BREWED_CA_CERTIFICATES`
+
If set, always use a Homebrew-installed `ca-certificates` rather than the system version. Automatically set if the system version is too old.
+
- `HOMEBREW_FORCE_BREWED_CURL`
If set, always use a Homebrew-installed `curl`(1) rather than the system version. Automatically set if the system version of `curl` is too old.
diff --git a/manpages/brew.1 b/manpages/brew.1
index 1ec0872291..94d48a3d6b 100644
--- a/manpages/brew.1
+++ b/manpages/brew.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BREW" "1" "September 2021" "Homebrew" "brew"
+.TH "BREW" "1" "October 2021" "Homebrew" "brew"
.
.SH "NAME"
\fBbrew\fR \- The Missing Package Manager for macOS (or Linux)
@@ -2826,6 +2826,12 @@ Output this many lines of output on formula \fBsystem\fR failures\.
A space\-separated list of licenses\. Homebrew will refuse to install a formula if it or any of its dependencies has a license on this list\.
.
.TP
+\fBHOMEBREW_FORCE_BREWED_CA_CERTIFICATES\fR
+.
+.br
+If set, always use a Homebrew\-installed \fBca\-certificates\fR rather than the system version\. Automatically set if the system version is too old\.
+.
+.TP
\fBHOMEBREW_FORCE_BREWED_CURL\fR
.
.br