Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authenticate downloaded binaries #17

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Commits on Jan 20, 2019

  1. Check in Bazel PGP information

    Summary:
    This includes the full public key for the Bazel team (48457EE0) as well
    as the ownertrust entry to mark the key as ultimately trusted within a
    keyring.
    
    The contents are included directly into the `bazelisk.py` file so that
    the script can be self-contained; we don’t have to worry about bundling
    it with any external assets.
    
    The ownertrust format was created by running importing the Bazel key
    into a clean keyring, running `gpg --edit-key 48457EE0` and setting the
    trust level to “ultimate”, then invoking `gpg --export-ownertrust`.
    
    Test Plan:
    Download <https://bazel.build/bazel-release.pub.gpg> and verify that it
    exactly matches the blob checked into this commit:
    
        $ curl --silent 'https://bazel.build/bazel-release.pub.gpg' | shasum -a 256
        30af2ca7abfb65987cd61802ca6e352aadc6129dfb5bfc9c81f16617bc3a4416  -
        $ sed -n '/BEGIN PGP/,/END PGP/p' bazelisk.py | shasum -a 256
        30af2ca7abfb65987cd61802ca6e352aadc6129dfb5bfc9c81f16617bc3a4416  -
    
    wchargin-branch: bazel-pgp-info
    wchargin committed Jan 20, 2019
    Configuration menu
    Copy the full SHA
    3f6698d View commit details
    Browse the repository at this point in the history
  2. Authenticate downloaded binaries

    Summary:
    This commit adds logic to authenticate all Bazel binaries that are
    downloaded, as long as the user has GPG installed. If a user does not
    have GPG installed, a new warning will be printed when a binary is
    downloaded, but Bazelisk will function the same way as before. (GPG is
    installed by default on Debian and Ubuntu.)
    
    No new subprocesses are spawned when an already-downloaded version of
    Bazel is run. The only appreciable overhead is incurred at download
    time.
    
    Resolves bazelbuild#15.
    
    Test Plan:
    
      - Remove the `~/.bazelisk` directory. Run `./bazelisk.py version`.
        Note that it downloads the latest binary and the latest signature,
        then prints “Authenticity verified” before invoking Bazel.
    
      - Run `./bazelisk.py version` again. Note that it does not verify the
        signature.
    
      - Remove the `~/.bazelisk` directory. Symlink `/bin/false` to
        `~/bin/gpg`, and ensure that the symlink precedes the real `gpg` on
        your path. Run Bazelisk, and note that it prints a warning that GPG
        is not available but executes Bazel anyway. Run Bazelisk again, and
        note that it does not print the warning (because it reuses the
        existing executable without reauthenticating). Remove the symlink.
    
      - Remove the `~/.bazelisk` directory. Edit `bazelisk.py`, changing the
        `determine_urls` function so that the returned `binary_url` is an
        arbitrary web page (like `http://example.com/`) but the signature
        URL is unchanged. Run Bazelisk, and note that Bazelisk reports,
        “Failed to authenticate binary!”, includes the GPG output (“BAD
        signature”), and aborts with exit code 2 _without_ invoking Bazel.
        Run `ls ~/.bazelisk/bin` and note that it does not include the
        invalid binary (though the signature is still there). Revert the
        changes to `bazelisk.py`.
    
      - Remove the `~/.bazelisk` directory. Create an arbitrary document and
        use `gpg --detach-sign` to sign it with a key that is not the Bazel
        signing key. Spawn a web server (`python -m SimpleHTTPServer`) to
        serve the “malicious executable” and its signature. Edit
        `bazelisk.py`, changing the `determine_urls` function to point both
        the binary and the signature to this local web server. Run Bazelisk,
        and note that it fails to authenticate the binary, with the message
        “public key not found”.
    
    Repeat the above steps in Python 2 and Python 3.
    
    Verify that your personal GnuPG database has not been modified (in
    particular, the Bazel key should not have been installed, and the trust
    settings should not have been modified).
    
    I have tested this on Linux with gpg (GnuPG) 1.4.20. I don’t see any
    reason that it shouldn’t work on macOS or Windows as long as the gpg(1)
    interfaces are the same.
    
    wchargin-branch: authenticate-binaries
    wchargin committed Jan 20, 2019
    Configuration menu
    Copy the full SHA
    7112761 View commit details
    Browse the repository at this point in the history
  3. DO NOT SUBMIT: debugging Buildkite failures

    Summary:
    The Linux tests passed, but the macOS tests failed with no useful
    output, and the Windows tests failed with an unexpected GPG invocation
    error with a strange path. This commit adds some print-statements in an
    attempt to investigate.
    
    Test Plan:
    Running `./bazelisk version` and `bazel test :bazelisk_test` both still
    work on Python 2 and 3 on Linux.
    
    wchargin-branch: authenticate-binaries
    wchargin committed Jan 20, 2019
    Configuration menu
    Copy the full SHA
    d01f032 View commit details
    Browse the repository at this point in the history
  4. DO NOT SUBMIT: ask for GPG info with homedir

    wchargin-branch: authenticate-binaries
    wchargin committed Jan 20, 2019
    Configuration menu
    Copy the full SHA
    5fb98bd View commit details
    Browse the repository at this point in the history
  5. DO NOT SUBMIT: rebased on master to prod buildkite

    wchargin-branch: authenticate-binaries
    wchargin committed Jan 20, 2019
    Configuration menu
    Copy the full SHA
    e67624f View commit details
    Browse the repository at this point in the history