From e52c2538321c199c430831ac4bef396cbf15ffcd Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 9 Apr 2024 10:45:44 -0400 Subject: [PATCH] attestation: simplify `gh` bootstrapping Signed-off-by: William Woodruff --- Library/Homebrew/attestation.rb | 9 ++++++++- Library/Homebrew/brew.sh | 16 ---------------- Library/Homebrew/cmd/update.sh | 13 +------------ Library/Homebrew/formula_installer.rb | 16 +++++++++++++++- Library/Homebrew/global.rb | 2 -- 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/Library/Homebrew/attestation.rb b/Library/Homebrew/attestation.rb index 2fee9fb641..554b510bea 100644 --- a/Library/Homebrew/attestation.rb +++ b/Library/Homebrew/attestation.rb @@ -22,6 +22,12 @@ module Homebrew # @api private BACKFILL_CUTOFF = DateTime.new(2024, 3, 14).freeze + def self.gh_executable + @gh_executable ||= with_env("HOMEBREW_VERIFY_ATTESTATIONS" => nil) do + ensure_executable!("gh") + end + end + # Verifies the given bottle against a cryptographic attestation of build provenance. # # The provenance is verified as originating from `signing_repo`, which is a `String` @@ -36,7 +42,8 @@ module Homebrew # # @api private def self.check_attestation(bottle, signing_repo, signing_workflow = nil) - cmd = [HOMEBREW_GH, "attestation", "verify", bottle.cached_download, "--repo", signing_repo, "--format", "json"] + cmd = [gh_executable, "attestation", "verify", bottle.cached_download, "--repo", signing_repo, "--format", + "json"] cmd += ["--cert-identity", signing_workflow] if signing_workflow.present? diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 7469af7b04..a00510b400 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -454,23 +454,8 @@ setup_git() { fi } -setup_gh() { - # This is set by the user environment. - # shellcheck disable=SC2154 - if [[ -n "${HOMEBREW_VERIFY_ATTESTATIONS}" && -x "${HOMEBREW_PREFIX}/opt/gh/bin/gh" ]] - then - HOMEBREW_GH="${HOMEBREW_PREFIX}/opt/gh/bin/gh" - elif [[ -n "${HOMEBREW_GH_PATH}" ]] - then - HOMEBREW_GH="${HOMEBREW_GH_PATH}" - else - HOMEBREW_GH="gh" - fi -} - setup_curl setup_git -setup_gh HOMEBREW_VERSION="$("${HOMEBREW_GIT}" -C "${HOMEBREW_REPOSITORY}" describe --tags --dirty --abbrev=7 2>/dev/null)" HOMEBREW_USER_AGENT_VERSION="${HOMEBREW_VERSION}" @@ -736,7 +721,6 @@ export HOMEBREW_API_DEFAULT_DOMAIN export HOMEBREW_BOTTLE_DEFAULT_DOMAIN export HOMEBREW_CURL_SPEED_LIMIT export HOMEBREW_CURL_SPEED_TIME -export HOMEBREW_GH if [[ -n "${HOMEBREW_MACOS}" && -x "/usr/bin/xcode-select" ]] then diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 152c0f31bb..b3806891df 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -15,7 +15,7 @@ # HOMEBREW_LIBRARY, HOMEBREW_PREFIX, HOMEBREW_REPOSITORY are set by bin/brew # HOMEBREW_BREW_DEFAULT_GIT_REMOTE, HOMEBREW_BREW_GIT_REMOTE, HOMEBREW_CACHE, HOMEBREW_CELLAR, HOMEBREW_CURL # HOMEBREW_DEV_CMD_RUN, HOMEBREW_FORCE_BREWED_CURL, HOMEBREW_FORCE_BREWED_GIT, HOMEBREW_SYSTEM_CURL_TOO_OLD -# HOMEBREW_USER_AGENT_CURL, HOMEBREW_GH are set by brew.sh +# HOMEBREW_USER_AGENT_CURL are set by brew.sh # shellcheck disable=SC2154 source "${HOMEBREW_LIBRARY}/Homebrew/utils/lock.sh" @@ -415,17 +415,6 @@ user account: EOS fi - # we need `gh` if the user enables attestation verification - if [[ -n "${HOMEBREW_VERIFY_ATTESTATIONS}" && ! -x "${HOMEBREW_GH}" ]] - then - # we cannot install `gh` if homebrew/core is unavailable. - # we don't enable attestations on `gh` itself, to prevent a bootstrap cycle. - if [[ -z "${HOMEBREW_CORE_AVAILABLE}" ]] || ! env -u HOMEBREW_VERIFY_ATTESTATIONS brew install gh - then - odie "'gh' must be installed and in your PATH!" - fi - 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 diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index 5bcecd2544..2d7985b160 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -1259,7 +1259,21 @@ on_request: installed_on_request?, options:) def pour if Homebrew::EnvConfig.verify_attestations? && formula.tap&.core_tap? ohai "Verifying attestation for #{formula.name}" - Homebrew::Attestation.check_core_attestation formula.bottle + begin + Homebrew::Attestation.check_core_attestation formula.bottle + rescue InvalidAttestationError => e + raise CannotInstallFormulaError, <<~EOS + The bottle for #{formula.name} has an invalid build provenance attestation. + + This may indicate that the bottle was not produced by the expected + tap, or was maliciously inserted into the expected tap's bottle + storage. + + Additional context: + + #{e} + EOS + end end HOMEBREW_CELLAR.cd do diff --git a/Library/Homebrew/global.rb b/Library/Homebrew/global.rb index f0a95bd670..fdebb4a470 100644 --- a/Library/Homebrew/global.rb +++ b/Library/Homebrew/global.rb @@ -66,8 +66,6 @@ HOMEBREW_PULL_OR_COMMIT_URL_REGEX = %r[https://github\.com/([\w-]+)/([\w-]+)?/(?:pull/(\d+)|commit/[0-9a-fA-F]{4,40})] HOMEBREW_BOTTLES_EXTNAME_REGEX = /\.([a-z0-9_]+)\.bottle\.(?:(\d+)\.)?tar\.gz$/ -HOMEBREW_GH = Pathname(ENV.fetch("HOMEBREW_GH")).freeze - require "env_config" require "macos_version" require "os"