From 4c8bf9c28d2e6094c46d379f0248a96ed3ca13b6 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:03 +0200 Subject: [PATCH 01/12] scripts: extract functions As a preparation to make the script easier to understand, we extract some of the sub tasks into functions. --- scripts/verify-install.sh | 217 +++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 108 deletions(-) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index c7c0a9b71..2dd03443b 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -9,6 +9,7 @@ MANIFEST_SELECTOR=". | select(.name | test(\"manifest-v.*(\\\\.txt)$\")) | .name SIGNATURE_SELECTOR=". | select(.name | test(\"manifest-.*(\\\\.sig)$\")) | .name" HEADER_JSON="Accept: application/json" HEADER_GH_JSON="Accept: application/vnd.github.v3+json" +MIN_REQUIRED_SIGNATURES=5 # All keys that can sign lnd releases. The key must be downloadable/importable # from the URL given after the space. @@ -22,6 +23,8 @@ KEYS+=("7E81EF6B9989A9CC93884803118759E83439A9B1 https://keybase.io/eugene_/pgp_ KEYS+=("7AB3D7F5911708842796513415BAADA29DA20D26 https://keybase.io/halseth/pgp_keys.asc") KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 https://keybase.io/arshbot/pgp_keys.asc") +TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX) + function check_command() { echo -n "Checking if $1 is installed... " if ! command -v "$1"; then @@ -30,6 +33,107 @@ function check_command() { fi } +function import_keys() { + for key in "${KEYS[@]}"; do + KEY_ID=$(echo $key | cut -d' ' -f1) + IMPORT_URL=$(echo $key | cut -d' ' -f2) + echo "Downloading and importing key $KEY_ID from $IMPORT_URL" + curl -L -s $IMPORT_URL | gpg --import + + # Make sure we actually imported the correct key. + if ! gpg --list-key "$KEY_ID"; then + echo "ERROR: Imported key from $IMPORT_URL doesn't match ID $KEY_ID." + fi + done +} + +function verify_signatures() { + # Download the JSON of the release itself. That'll contain the release ID we + # need for the next call. + RELEASE_JSON=$(curl -L -s -H "$HEADER_JSON" "$RELEASE_URL/$LND_VERSION") + + TAG_NAME=$(echo $RELEASE_JSON | jq -r '.tag_name') + RELEASE_ID=$(echo $RELEASE_JSON | jq -r '.id') + echo "Release $TAG_NAME found with ID $RELEASE_ID" + + # Now download the asset list and filter by the manifest and the signatures. + ASSETS=$(curl -L -s -H "$HEADER_GH_JSON" "$API_URL/$RELEASE_ID" | jq -c '.assets[]') + MANIFEST=$(echo $ASSETS | jq -r "$MANIFEST_SELECTOR") + SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR") + + # Download the main "manifest-*.txt" and all "manifest-*.sig" files containing + # the detached signatures. + echo "Downloading $MANIFEST" + curl -L -s -o "$TEMP_DIR/$MANIFEST" "$RELEASE_URL/download/$LND_VERSION/$MANIFEST" + + for signature in $SIGNATURES; do + echo "Downloading $signature" + curl -L -s -o "$TEMP_DIR/$signature" "$RELEASE_URL/download/$LND_VERSION/$signature" + done + + echo "" + + # Before we even look at the content of the manifest, we first want to make + # sure the signatures actually sign that exact manifest. + NUM_CHECKS=0 + for signature in $SIGNATURES; do + echo "Verifying $signature" + if gpg --verify "$TEMP_DIR/$signature" "$TEMP_DIR/$MANIFEST" 2>&1 | grep -q "Good signature"; then + echo "Signature for $signature appears valid: " + gpg --verify "$TEMP_DIR/$signature" "$TEMP_DIR/$MANIFEST" 2>&1 | grep "using" + elif gpg --verify "$TEMP_DIR/$signature" 2>&1 | grep -q "No public key"; then + echo "Unable to verify signature $signature, no key available, skipping" + continue + else + echo "ERROR: Did not get valid signature for $MANIFEST in $signature!" + echo " The developer signature $signature disagrees on the expected" + echo " release binaries in $MANIFEST. The release may have been faulty or" + echo " was backdoored." + exit 1 + fi + + echo "Verified $signature against $MANIFEST" + ((NUM_CHECKS=NUM_CHECKS+1)) + done + + # We want at least five signatures (out of seven public keys) that sign the + # hashes of the binaries we have installed. If we arrive here without exiting, + # it means no signature manifests were uploaded (yet) with the correct naming + # pattern. + if [[ $NUM_CHECKS -lt $MIN_REQUIRED_SIGNATURES ]]; then + echo "ERROR: Not enough valid signatures found!" + echo " Valid signatures found: $NUM_CHECKS" + echo " Valid signatures required: $MIN_REQUIRED_SIGNATURES" + echo + echo " Make sure the release $LND_VERSION contains the required " + echo " number of signatures on the manifest, or wait until more " + echo " signatures have been added to the release." + exit 1 + fi +} + +function check_hash() { + # If we're inside the docker image, there should be a shasums.txt file in the + # root directory. If that's the case, we first want to make sure we still have + # the same hash as we did when building the image. + if [[ -f /shasums.txt ]]; then + if ! grep -q "$1" /shasums.txt; then + echo "ERROR: Hash $1 for $2 not found in /shasums.txt: " + cat /shasums.txt + exit 1 + fi + fi + + if ! grep -q "^$1" "$TEMP_DIR/$MANIFEST"; then + echo "ERROR: Hash $1 for $2 not found in $MANIFEST: " + cat "$TEMP_DIR/$MANIFEST" + echo " The expected release binaries have been verified with the developer " + echo " signatures. Your binary's hash does not match the expected release " + echo " binary hashes. Make sure you're using an official binary." + exit 1 + fi +} + # By default we're picking up lnd and lncli from the system $PATH. LND_BIN=$(which lnd) LNCLI_BIN=$(which lncli) @@ -104,121 +208,18 @@ if [[ ${#LNCLI_SUM} -ne 64 ]]; then exit 1 fi -# If we're inside the docker image, there should be a shasums.txt file in the -# root directory. If that's the case, we first want to make sure we still have -# the same hash as we did when building the image. -if [[ -f /shasums.txt ]]; then - if ! grep -q "$LND_SUM" /shasums.txt; then - echo "ERROR: Hash $LND_SUM for lnd not found in /shasums.txt: " - cat /shasums.txt - exit 1 - fi - if ! grep -q "$LNCLI_SUM" /shasums.txt; then - echo "ERROR: Hash $LNCLI_SUM for lnd not found in /shasums.txt: " - cat /shasums.txt - exit 1 - fi -fi - # Import all the signing keys. -for key in "${KEYS[@]}"; do - KEY_ID=$(echo $key | cut -d' ' -f1) - IMPORT_URL=$(echo $key | cut -d' ' -f2) - echo "Downloading and importing key $KEY_ID from $IMPORT_URL" - curl -L -s $IMPORT_URL | gpg --import - - # Make sure we actually imported the correct key. - if ! gpg --list-key "$KEY_ID"; then - echo "ERROR: Imported key from $IMPORT_URL doesn't match ID $KEY_ID." - fi -done +import_keys echo "" -# Download the JSON of the release itself. That'll contain the release ID we need for the next call. -RELEASE_JSON=$(curl -L -s -H "$HEADER_JSON" "$RELEASE_URL/$LND_VERSION") - -TAG_NAME=$(echo $RELEASE_JSON | jq -r '.tag_name') -RELEASE_ID=$(echo $RELEASE_JSON | jq -r '.id') -echo "Release $TAG_NAME found with ID $RELEASE_ID" - -# Now download the asset list and filter by the manifest and the signatures. -ASSETS=$(curl -L -s -H "$HEADER_GH_JSON" "$API_URL/$RELEASE_ID" | jq -c '.assets[]') -MANIFEST=$(echo $ASSETS | jq -r "$MANIFEST_SELECTOR") -SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR") - -# Download the main "manifest-*.txt" and all "manifest-*.sig" files containing -# the detached signatures. -TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX) -echo "Downloading $MANIFEST" -curl -L -s -o "$TEMP_DIR/$MANIFEST" "$RELEASE_URL/download/$LND_VERSION/$MANIFEST" - -for signature in $SIGNATURES; do - echo "Downloading $signature" - curl -L -s -o "$TEMP_DIR/$signature" "$RELEASE_URL/download/$LND_VERSION/$signature" -done - -echo "" -cd $TEMP_DIR || exit 1 - -# Before we even look at the content of the manifest, we first want to make sure -# the signatures actually sign that exact manifest. -NUM_CHECKS=0 -for signature in $SIGNATURES; do - echo "Verifying $signature" - if gpg --verify "$signature" "$MANIFEST" 2>&1 | grep -q "Good signature"; then - echo "Signature for $signature appears valid: " - gpg --verify "$signature" "$MANIFEST" 2>&1 | grep "using" - elif gpg --verify "$signature" 2>&1 | grep -q "No public key"; then - echo "Unable to verify signature $signature, no key available, skipping" - continue - else - echo "ERROR: Did not get valid signature for $MANIFEST in $signature!" - echo " The developer signature $signature disagrees on the expected" - echo " release binaries in $MANIFEST. The release may have been faulty or" - echo " was backdoored." - exit 1 - fi - - echo "Verified $signature against $MANIFEST" - ((NUM_CHECKS=NUM_CHECKS+1)) -done - -# We want at least five signatures (out of seven public keys) that sign the -# hashes of the binaries we have installed. If we arrive here without exiting, -# it means no signature manifests were uploaded (yet) with the correct naming -# pattern. -MIN_REQUIRED_SIGNATURES=5 -if [[ $NUM_CHECKS -lt $MIN_REQUIRED_SIGNATURES ]]; then - echo "ERROR: Not enough valid signatures found!" - echo " Valid signatures found: $NUM_CHECKS" - echo " Valid signatures required: $MIN_REQUIRED_SIGNATURES" - echo - echo " Make sure the release $LND_VERSION contains the required " - echo " number of signatures on the manifest, or wait until more " - echo " signatures have been added to the release." - exit 1 -fi +# Verify and count the signatures. +verify_signatures # Then make sure that the hash of the installed binaries can be found in the # manifest that we now have verified the signatures for. -if ! grep -q "^$LND_SUM" "$MANIFEST"; then - echo "ERROR: Hash $LND_SUM for lnd not found in $MANIFEST: " - cat "$MANIFEST" - echo " The expected release binaries have been verified with the developer " - echo " signatures. Your binary's hash does not match the expected release " - echo " binary hashes. Make sure you're using an official binary." - exit 1 -fi - -if ! grep -q "^$LNCLI_SUM" "$MANIFEST"; then - echo "ERROR: Hash $LNCLI_SUM for lncli not found in $MANIFEST: " - cat "$MANIFEST" - echo " The expected release binaries have been verified with the developer " - echo " signatures. Your binary's hash does not match the expected release " - echo " binary hashes. Make sure you're using an official binary." - exit 1 -fi +check_hash "$LND_SUM" "lnd" +check_hash "$LNCLI_SUM" "lncli" echo "" echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers." From fc4a16b672d8de5599ab24ee33702d22801f79b4 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 27 Sep 2021 11:03:04 +0200 Subject: [PATCH 02/12] scripts/verify-install.sh: pass expected version as argument This removes a vulnerability brought up by @Kixunil where both the lnd and lncli binaries are executed to obtain their version before they have been verified against the release. A malicious binary could have already compromised the user's system before any of the checks had been performed. This commit it split out from the doc changes so that it can easily be cherry-picked to master/0.13.0. --- scripts/verify-install.sh | 113 ++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 54 deletions(-) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index 2dd03443b..f1ba638fc 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -33,6 +33,15 @@ function check_command() { fi } +function verify_version() { + version_regex="^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]" + if [[ ! "$1" =~ $version_regex ]]; then + echo "ERROR: Invalid expected version detected: $1" + exit 1 + fi + echo "Expected version for binaries: $1" +} + function import_keys() { for key in "${KEYS[@]}"; do KEY_ID=$(echo $key | cut -d' ' -f1) @@ -50,7 +59,7 @@ function import_keys() { function verify_signatures() { # Download the JSON of the release itself. That'll contain the release ID we # need for the next call. - RELEASE_JSON=$(curl -L -s -H "$HEADER_JSON" "$RELEASE_URL/$LND_VERSION") + RELEASE_JSON=$(curl -L -s -H "$HEADER_JSON" "$RELEASE_URL/$VERSION") TAG_NAME=$(echo $RELEASE_JSON | jq -r '.tag_name') RELEASE_ID=$(echo $RELEASE_JSON | jq -r '.id') @@ -64,11 +73,11 @@ function verify_signatures() { # Download the main "manifest-*.txt" and all "manifest-*.sig" files containing # the detached signatures. echo "Downloading $MANIFEST" - curl -L -s -o "$TEMP_DIR/$MANIFEST" "$RELEASE_URL/download/$LND_VERSION/$MANIFEST" + curl -L -s -o "$TEMP_DIR/$MANIFEST" "$RELEASE_URL/download/$VERSION/$MANIFEST" for signature in $SIGNATURES; do echo "Downloading $signature" - curl -L -s -o "$TEMP_DIR/$signature" "$RELEASE_URL/download/$LND_VERSION/$signature" + curl -L -s -o "$TEMP_DIR/$signature" "$RELEASE_URL/download/$VERSION/$signature" done echo "" @@ -105,7 +114,7 @@ function verify_signatures() { echo " Valid signatures found: $NUM_CHECKS" echo " Valid signatures required: $MIN_REQUIRED_SIGNATURES" echo - echo " Make sure the release $LND_VERSION contains the required " + echo " Make sure the release $VERSION contains the required " echo " number of signatures on the manifest, or wait until more " echo " signatures have been added to the release." exit 1 @@ -113,19 +122,39 @@ function verify_signatures() { } function check_hash() { + # Make this script compatible with both linux and *nix. + SHA_CMD="sha256sum" + if ! command -v "$SHA_CMD" > /dev/null; then + if command -v "shasum"; then + SHA_CMD="shasum -a 256" + else + echo "ERROR: no SHA256 sum binary installed!" + exit 1 + fi + fi + SUM=$($SHA_CMD "$1" | cut -d' ' -f1) + + # Make sure the hash was actually calculated by looking at its length. + if [[ ${#SUM} -ne 64 ]]; then + echo "ERROR: Invalid hash for $2: $SUM!" + exit 1 + fi + + echo "Verifying $1 as version $VERSION with SHA256 sum $SUM" + # If we're inside the docker image, there should be a shasums.txt file in the # root directory. If that's the case, we first want to make sure we still have # the same hash as we did when building the image. if [[ -f /shasums.txt ]]; then - if ! grep -q "$1" /shasums.txt; then - echo "ERROR: Hash $1 for $2 not found in /shasums.txt: " + if ! grep -q "$SUM" /shasums.txt; then + echo "ERROR: Hash $SUM for $2 not found in /shasums.txt: " cat /shasums.txt exit 1 fi fi - if ! grep -q "^$1" "$TEMP_DIR/$MANIFEST"; then - echo "ERROR: Hash $1 for $2 not found in $MANIFEST: " + if ! grep -q "^$SUM" "$TEMP_DIR/$MANIFEST"; then + echo "ERROR: Hash $SUM for $2 not found in $MANIFEST: " cat "$TEMP_DIR/$MANIFEST" echo " The expected release binaries have been verified with the developer " echo " signatures. Your binary's hash does not match the expected release " @@ -138,6 +167,19 @@ function check_hash() { LND_BIN=$(which lnd) LNCLI_BIN=$(which lncli) +if [[ $# -eq 0 ]]; then + echo "ERROR: missing expected version!" + echo "Usage: verify-install.sh expected-version [path-to-lnd-binary path-to-lncli-binary]" + exit 1 +fi + +# The first argument should be the expected version of the binaries. +VERSION=$1 +shift + +# Verify that the expected version is well-formed. +verify_version "$VERSION" + # If exactly two parameters are specified, we expect the first one to be lnd and # the second one to be lncli. if [[ $# -eq 2 ]]; then @@ -154,60 +196,23 @@ if [[ $# -eq 2 ]]; then exit 1 fi elif [[ $# -eq 0 ]]; then - # Make sure both binaries can be found and are executable. - check_command lnd - check_command lncli + # By default we're picking up lnd and lncli from the system $PATH. + LND_BIN=$(which lnd) + LNCLI_BIN=$(which lncli) else echo "ERROR: invalid number of parameters!" echo "Usage: verify-install.sh [lnd-binary lncli-binary]" exit 1 fi +# Make sure both binaries can be found and are executable. +check_command "$LND_BIN" +check_command "$LNCLI_BIN" + check_command curl check_command jq check_command gpg -LND_VERSION=$($LND_BIN --version | cut -d'=' -f2) -LNCLI_VERSION=$($LNCLI_BIN --version | cut -d'=' -f2) - -# Make this script compatible with both linux and *nix. -SHA_CMD="sha256sum" -if ! command -v "$SHA_CMD"; then - if command -v "shasum"; then - SHA_CMD="shasum -a 256" - else - echo "ERROR: no SHA256 sum binary installed!" - exit 1 - fi -fi -LND_SUM=$($SHA_CMD $LND_BIN | cut -d' ' -f1) -LNCLI_SUM=$($SHA_CMD $LNCLI_BIN | cut -d' ' -f1) - -echo "Detected lnd $LND_BIN version $LND_VERSION with SHA256 sum $LND_SUM" -echo "Detected lncli $LNCLI_BIN version $LNCLI_VERSION with SHA256 sum $LNCLI_SUM" - -# Make sure lnd and lncli are installed with the same version and is an actual -# version string. -if [[ "$LNCLI_VERSION" != "$LND_VERSION" ]]; then - echo "ERROR: Version $LNCLI_VERSION of lncli does not match $LND_VERSION of lnd!" - exit 1 -fi -version_regex="^v[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]" -if [[ ! "$LND_VERSION" =~ $version_regex ]]; then - echo "ERROR: Invalid version of lnd detected: $LND_VERSION" - exit 1 -fi - -# Make sure the hash was actually calculated by looking at its length. -if [[ ${#LND_SUM} -ne 64 ]]; then - echo "ERROR: Invalid hash for lnd: $LND_SUM!" - exit 1 -fi -if [[ ${#LNCLI_SUM} -ne 64 ]]; then - echo "ERROR: Invalid hash for lncli: $LNCLI_SUM!" - exit 1 -fi - # Import all the signing keys. import_keys @@ -218,8 +223,8 @@ verify_signatures # Then make sure that the hash of the installed binaries can be found in the # manifest that we now have verified the signatures for. -check_hash "$LND_SUM" "lnd" -check_hash "$LNCLI_SUM" "lncli" +check_hash "$LND_BIN" "lnd" +check_hash "$LNCLI_BIN" "lncli" echo "" echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers." From 50d27e8050177832403e16b02c33812590a5ba1d Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 27 Sep 2021 11:03:05 +0200 Subject: [PATCH 03/12] docs: remove unnecessary docker pull from release verification Docker will automatically pull the image if it isn't found locally. --- .github/workflows/release.yaml | 1 - docs/DOCKER.md | 1 - docs/release.md | 1 - 3 files changed, 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fde41f5f3..e1b1d850c 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -113,7 +113,6 @@ jobs: To verify the `lnd` and `lncli` binaries inside the docker images against the signed, reproducible release binaries, there is a verification script in the image that can be called (before starting the container for example): ```shell - $ docker pull lightninglabs/lnd:${{ env.RELEASE_VERSION }} $ docker run --rm --entrypoint="" lightninglabs/lnd:${{ env.RELEASE_VERSION }} /verify-install.sh $ OK=$? $ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done diff --git a/docs/DOCKER.md b/docs/DOCKER.md index 62f00111f..e0163511e 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -61,7 +61,6 @@ script in the image that can be called (before starting the container for example): ```shell -⛰ docker pull lightninglabs/lnd:v0.12.0-beta ⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh ⛰ OK=$? ⛰ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done diff --git a/docs/release.md b/docs/release.md index 42f2b8df3..d0b84efca 100644 --- a/docs/release.md +++ b/docs/release.md @@ -99,7 +99,6 @@ script in the image that can be called (before starting the container for example): ```shell -⛰ docker pull lightninglabs/lnd:v0.12.0-beta ⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh ⛰ OK=$? ⛰ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done From af3fa69d052528f22fd9f2ad8a2a4a4a40098a92 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 27 Sep 2021 11:03:07 +0200 Subject: [PATCH 04/12] docs: update release verification scripts for v0.12.1-beta --- .github/workflows/release.yaml | 2 +- docs/DOCKER.md | 2 +- docs/release.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e1b1d850c..a6a603488 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -113,7 +113,7 @@ jobs: To verify the `lnd` and `lncli` binaries inside the docker images against the signed, reproducible release binaries, there is a verification script in the image that can be called (before starting the container for example): ```shell - $ docker run --rm --entrypoint="" lightninglabs/lnd:${{ env.RELEASE_VERSION }} /verify-install.sh + $ docker run --rm --entrypoint="" lightninglabs/lnd:${{ env.RELEASE_VERSION }} /verify-install.sh ${{ env.RELEASE_VERSION }} $ OK=$? $ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done $ docker run lightninglabs/lnd [command-line options] diff --git a/docs/DOCKER.md b/docs/DOCKER.md index e0163511e..74142fcaa 100644 --- a/docs/DOCKER.md +++ b/docs/DOCKER.md @@ -61,7 +61,7 @@ script in the image that can be called (before starting the container for example): ```shell -⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh +⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.1-beta /verify-install.sh v0.12.1-beta ⛰ OK=$? ⛰ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done ⛰ docker run lightninglabs/lnd [command-line options] diff --git a/docs/release.md b/docs/release.md index d0b84efca..30e6e5727 100644 --- a/docs/release.md +++ b/docs/release.md @@ -99,7 +99,7 @@ script in the image that can be called (before starting the container for example): ```shell -⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh +⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.1-beta /verify-install.sh v0.12.1-beta ⛰ OK=$? ⛰ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done ⛰ docker run lightninglabs/lnd [command-line options] From f6c66ca98098451c51d69c1eae1344d870c474b0 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:08 +0200 Subject: [PATCH 05/12] scripts: add signing keys to repo Instead of importing the keys from Keybase, we add all the signing keys to the repository. In addition to having the key file present each key's ID must also be added to the verification script. This acts as a double check that the correct key is added and makes a key change more explicit. --- scripts/keys/Crypt-iQ.asc | 31 ++++ scripts/keys/README.md | 15 ++ scripts/keys/arshbot.asc | 52 ++++++ scripts/keys/bhandras.asc | 41 +++++ scripts/keys/carlaKC.asc | 66 ++++++++ scripts/keys/cfromknecht.asc | 52 ++++++ scripts/keys/guggero.asc | 302 +++++++++++++++++++++++++++++++++++ scripts/keys/halseth.asc | 30 ++++ scripts/keys/roasbeef.asc | 109 +++++++++++++ scripts/keys/wpaulino.asc | 109 +++++++++++++ scripts/verify-install.sh | 66 ++++++-- 11 files changed, 856 insertions(+), 17 deletions(-) create mode 100644 scripts/keys/Crypt-iQ.asc create mode 100644 scripts/keys/README.md create mode 100644 scripts/keys/arshbot.asc create mode 100644 scripts/keys/bhandras.asc create mode 100644 scripts/keys/carlaKC.asc create mode 100644 scripts/keys/cfromknecht.asc create mode 100644 scripts/keys/guggero.asc create mode 100644 scripts/keys/halseth.asc create mode 100644 scripts/keys/roasbeef.asc create mode 100644 scripts/keys/wpaulino.asc diff --git a/scripts/keys/Crypt-iQ.asc b/scripts/keys/Crypt-iQ.asc new file mode 100644 index 000000000..0ee20d0c8 --- /dev/null +++ b/scripts/keys/Crypt-iQ.asc @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: GPGTools - https://gpgtools.org + +mQENBFzxMZ4BCAC5rjT2bbyqMNbHEVMs5Oi7y77eOHhwf1KRx5UALWoH1eDb6/kH ++ZnTUjL2h11aN+8cDJCCleFfARXxvxo97TSyz4V+VjHebKu3kulFtqLcgR2C4BeE +oJqe17sE3+iJQt4+uirl1IEF/fe0DMtKbc55V5LIpvmB+s9U7RmGYNqCCmva48sj +CmYhig885C55s/tUsCA/OQcxES4lZhcY7C/+LowvummXEOLeUUHnFyTJdX2QWBLg +l0zXt98JiY9mZGoWQk9Syb3tkMLLL0YY7AZs1BmsNn2gBpPBTHkmMXxO2khX4mlB +r6clRO7A1oci58D9/+f2GRzfLJjxoTCXqCs3ABEBAAG0J2V1Z2VuZSBzaWVnZWwg +KDpEKSA8ZWx6ZWlnZWxAZ21haWwuY29tPokBVAQTAQoAPgIbAwULCQgHAgYVCgkI +CwIEFgIDAQIeAQIXgBYhBH6B72uZianMk4hIAxGHWeg0OamxBQJfhf0tBQkGVzKP +AAoJEBGHWeg0OamxyB8H/jwmQnlbxf1/q6C75W2/Mf+/0VH0A2q6pSN0aBvbDvHJ +jNYp7uWynLHYFWrHHVSsMg3nzrubiNtjUy001+hVKcD4TB33b1YRl5XQk87OjHZl +Kprj2351ypAjnxbsaYRIqu6Bvpfgj6TkR9xpZ+3rVRA7V1CfSyTJOTi1VzBNlO6m +UsHh5dSlT3G6ESU31MbP4lp2H1XTik5uymCTSeCIn/TdqYQen9ZNxjJGkHjszUrw +x4S4Rz/IylBVX1FffdqMJoD6RoOeScpyET4lHF1xi1xZkdgwx0etkmOW9O1dkhmg +ysJnHNZlYeKklCf20fwhqVOxpaac0nqOZnILbMFj2lK5AQ0EXPExngEIAMA37Zv0 +SyIQLzRb7hF512aut6gveACkWAy1OktuSc8/GahP1pB1gtqBoS1S4Lv3uyujnh8j +rqx/r5zoCEt2y6byf8qx/jQMZ/4IH+ZGlA6guNz871rjGIDO/6OE9O0n9v4PztDv +ZTbqGTdwn4Vev62UUUTZJcYjIimgU5voz998tFvdOmReo5KlQfZnVEMI62xARssy +9BQ0g7ncmm0RyjQMNwchIF9NfrJWk2JF3zRqVP1Aix41gflOomCKvij9spzAzRzA +so4e67+NMpVzW9jfPG16AoBl9j16uHoYYlFkpkeNFDQV0BjTpJ6v571IDHJrAyDq +x7Zf6DQruVs95CcAEQEAAYkBPAQYAQoAJgIbDBYhBH6B72uZianMk4hIAxGHWeg0 +OamxBQJfhf1DBQkGVzKlAAoJEBGHWeg0Oamxo9IIAII3/Ni18V2sDcNyUhuznJLl +I9kAv8y10OGu13iOp1bifVDgnoZuEvX2Zhg+GqbbR6iWjWGDzQfxrmvV5YzDvDM9 +rjTaeFAX3EJbE28x/7ERLGHuhV4BVQYzmUGMiy0mjogZnefp4RyfNjR62qBWm8tU +ap5ly7Phxkuup31BDxXKamr/+gGXCz3mfV2+Q73PqM7Nui9hR6rZbiO7JxEEWfpG +01Oh0a65wVvNg804czcUqK7sHAKMzKunM/9JRx5hBJIXN8tl/1g2RpaKm96/lfVe +6Z9yTNmRMIo6JCNnWbTPm3Qay134M59nDATb0ffPRCFW8SJeTRYrX1lnAv5Ew9M= +=x0si +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/README.md b/scripts/keys/README.md new file mode 100644 index 000000000..8d1ec7a12 --- /dev/null +++ b/scripts/keys/README.md @@ -0,0 +1,15 @@ +# Release verification keys + +This directory contains all keys that are currently signing `lnd` releases. + +The name of the file must match exactly the suffix that user is going to use +when signing a release. +For example, if the key is called `eugene_.asc` then that user must upload a +signature file called `manifest-eugene_-v0.xx.yy-beta.sig`, otherwise the +verification will fail. See [the release +documentation](../../docs/release.md#signing-an-existing-manifest-file) for +details on how to create the signature. + +In addition to adding the key file here as a `.asc` file the +`scripts/verify-install.sh` file must also be updated with the key ID and the +reference to the key file. diff --git a/scripts/keys/arshbot.asc b/scripts/keys/arshbot.asc new file mode 100644 index 000000000..079f1e518 --- /dev/null +++ b/scripts/keys/arshbot.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +tS+lWBS+3CAU3A== +=qhXJ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/bhandras.asc b/scripts/keys/bhandras.asc new file mode 100644 index 000000000..fc0cf449f --- /dev/null +++ b/scripts/keys/bhandras.asc @@ -0,0 +1,41 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=EosS +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/carlaKC.asc b/scripts/keys/carlaKC.asc new file mode 100644 index 000000000..493541ac4 --- /dev/null +++ b/scripts/keys/carlaKC.asc @@ -0,0 +1,66 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Comment: https://keybase.io/carlakirkcohen +Version: Keybase Go 1.0.47 (darwin) + +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 +8mNq +=2000 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/cfromknecht.asc b/scripts/keys/cfromknecht.asc new file mode 100644 index 000000000..2599a9418 --- /dev/null +++ b/scripts/keys/cfromknecht.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBFqe/pgBEADGITCXMdzn7+o0rpm4FTJu+LbPSPH+vZi5lbh8vHJ4R0KOMqhx +zMcTLpcD962rmWD8aPq77iX91YXr+yqfpaI6Is2w8ZPjwUFP+Q541XN2djDhNFfu +kPxI4PdMqIuDjPPbS4GIZiRHdCVgzzyvpJTBwBGEZJ204TmNoLWZ9zCh0AzpsJxr +y4RHy+o6Gy4un1n2pu8tkCmaiEtzmRO+ahmNVHNeYUgUT4nDEMAU3VrkmNMctlxJ +5Ng8k1BZ9foQrsjZg7Ovrhi+/L7YWP73TmY4jWxM+P52UyKyPOJiTqg+Xe/1aGPR +ij1KJYoRqWNBG8euIQzcDt4uExndJ5SJtidF/8leCpQGmxDSYDcsAv3/93z/JGGz +Q50j4dwDc11hzPJ9PBq1MLaGEYpQgJpgLx7uXAgu5eRZpFYseFmulbSDwdft78wS +I6K4+9xvzG1LAx9AOomwXj5/I8tL8Cc+IusG6fQOGmHeQO8ekFTYBj9BU0vTLn6F +8/5Bky+zSjx+IRgLpacSjkQGHruDF7JZN1bbAjEGhmMwW0jGzs9JC+HW89w0Yq9G +sFjhyQEoMF9eWMVuhN9BxQ7DXAjXzuCl2MamwC0Aedv/qxExfRlbB0JrIPwl2w7B +37e/26BBlUCrke4yhk0kNHbj6PiLd4Fuv3Bn20nLw4TBaHjqxn4knhnpmQARAQAB +tDBDb25uZXIgRnJvbWtuZWNodCA8Y29ubmVyQGxpZ2h0bmluZy5lbmdpbmVlcmlu +Zz6JAlQEEwEIAD4CGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AWIQScjWGGinxJ +IAOydE7n1ze2f6WSxwUCYEPADgUJB4X09gAKCRDn1ze2f6WSx4dbD/94A8wo2aum +e7n5I6lj5OIp/fwGOFuT+6lizZtewPuFMHv8qo0D7Gx02YHglB47o/LmVptSavX8 +BXqVhA0ZopAP81vtvN/VYyax8Lo9VrnrVQ1nLPP1XOVeFDm7IxFUsmFE7AAEkJlv +cL1mmquxWfg40o6qxehoHy7mKqWI2ns1MaLFLJEdz38PVgGOrVjRR0o5vq2wBC2Q +PoaxdFKbcycnhLx1Kqq9a69GOt21EKg2JBOgwvhv/ejYzg0gH/OU9vvG82vIAA0b +Xee/nGrRSpsQmzfYl6g/TdmbCzjdv5ZK5+A0VnJvGIqEcuy8XhZZJ6jN9sM8YYAs +f4oDRaEOcqldD+jmNwCb88Jxt+L12k+2a9H3ww74WlbQ2SxDLwkG9LhklIA4Op1i +//LxTQ2kBZM747SE4UFvQYIQHvBgHD1zKvcXn5H9dk5diinAXCsULocEQ5xGIJro +AN4QOlJcF7Po/KcSgKmYHL5FCNW2lUJ1VmG3AWydErkbidFiKtPJmWJFeXxDxal9 +/a3vt5UBSaKyoHC1oWIhfljRkV4QONFr0viEKb+4QAJzYaDZ8HRjLaS00OjUWaIb +Bj/qoU+FUGxBLUaTBSoEDDJL26DezHP6J/cvlgmxi0lRiFkHKmTmtoNJEj/cxa7N +YDDsy2bknvVzhs8wPg+9lm00V8Niy8oNubkCDQRanv6YARAA3we2me6D9FmKwv2w +GmsoJUBoaX1E9gO/YKEyQT8638UMMjJIPH0uVovDk6OGNhykPP9Z2MGDZJNFxBh2 +dabxL/6QJLjYebseRurN8ruDewWhI0op3z0JkKvvUKNJeCLGQEqkbnpKDZ1SaIai +2rDlytsrSo37KFp+sd2+WSJUgk5nzjSA1d1CCPPUQVqWsez8cDuir4TdAANyWsne +XvxmTdnZAHpWFPjnjkypzBH7GIAudo7Gj0SGSPmkpmA2WZcw7vIYm2O1dUxfMVXQ +7+znEkckZkdGLcmABOgTAkm7GseCTvnfnt0+TNgKTUKXGKe08nRAbqgysnwFDyG2 +lCey1Ntsz+D3mZfrAa0M9tIQZnjUOLmfr5q2UPjeOJFFGqkpeTb62JLsZpobvoOm +gNmzGKr/djvihqVQM/bNIYE3OIrt+JOaB6Kb/bH4qgDd70TEXkX8efsmQtzcVT+9 +KLHyVvBjIQuoXqn84k26U5WQSEg889iA3eZ4rFvQrB4LZk0ryHC+bcroEEmU/LLD +zZEXyAfCes0lzg9ZIh+3LSqnvD/dIeaVgfaV5AThfKtOwpO8NZF/TkGaXfwC+S8R +/joyAWYJyIKs2ibu42CB+wnrJyb4ujJznCuzY5rW+1CC5+FlfYOaiWNovT9NU9S+ +jLprWDW1CydtfDdbjF9gjyQj0iUAEQEAAYkCPAQYAQgAJgIbDBYhBJyNYYaKfEkg +A7J0TufXN7Z/pZLHBQJeYdPFBQkFpAitAAoJEOfXN7Z/pZLHOCsP/jgEJXk8mZW8 ++d5shUWe3Hx10JiVPBymoDnv3NtJ8a9LGaJcsbKIjpzysMeZ5cW04l33NM+eaWb4 +/ogX98yak4JNYpaiDuloDyNAM7SqH1WdNMqVj3WXvH8Gw/azhDy7xudOGFQi6nTB +14LsgK7X2zAVmxTu9kdwYh64APF2X48WqFQKd85gX35V5OFPGQbpI7viMFC9Sq7U +E27VsyzNpt6hLfb1enEm3t8E6Fi7z5uxPhoX13FShm1ho6U3hQzc27JH08MWxxOE +w8mcwg5l7ktpQOzUkFHvaPNKKAEQGZ4miOuZFajDWdz3eDe5bRrUYo1h6NR5Unv9 +9ZgCfmVuuHYfw+uwEiQcXb4F6UXHwjp8iJtFM4AOcG93nD+1ZkX6U6pneSF5O3cf +EiEKQBu7MxiyWm7L1V+asR2uPWs9mXl1TNC2rlsHKCFJ8We0Xb1btfmlpTeINjPx +yrERZmWUl5bY+sziSfX0H07v49jgPxUilBMxQaqrw0pOhzodq+R+R1OJX9aV7gfz +KWov0Rq2/2TGoeIlVz0Y/mMDCz5ONRn21l1I+HBqjeEBFws8w41cQsKFl5+5dk4m +LZ+g6JVoJ8rlqbMKS2TwhXHwC7ZCWn6w1WI74nJAkn+ULTXFUSwrsJrvwVVqY5YE +P9FcOPI4UCyAsnvRuobOOGZjkARfXg/5 +=OCU6 +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/guggero.asc b/scripts/keys/guggero.asc new file mode 100644 index 000000000..f46bb0ad7 --- /dev/null +++ b/scripts/keys/guggero.asc @@ -0,0 +1,302 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +aoyvLEhT2aQIgSCx3tGTDWm3ZvObh+M= +=vQ0v +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/halseth.asc b/scripts/keys/halseth.asc new file mode 100644 index 000000000..c75713948 --- /dev/null +++ b/scripts/keys/halseth.asc @@ -0,0 +1,30 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBFmMHhMBCADJErQPmbQYFlVwtKD7UDLfm28ZKUyAt7WDzgYN/aPL3eQb1xOT +NHI20F8TN3GXb3yy+57ETLy4GXADrb7BxXbvYOsFMZuoadcbnRmgKV28R6VRsSGL +Zyp5Ol5KrR39I5G6FdIIP/qSER0oSe/2KySRgob8YQlF24NLI/5RKgyayj4kdaou +j7ghVpWv8MpMzM1TEKlerOBhU88B6l0vjmJcxHxbCkc5xqqDQya7Ll8VAnLIYYNF +WTduugWn8JC9Ys3+emLI78VMoaMEMkBeUS/zrTFDZB6DufDCsNtw9YhM/anok74d +5kvcQctnrINiHP5EJf7yJ1PREAmW22ZMla7TABEBAAG0I0pvaGFuIFQgSGFsc2V0 +aCA8am9oYW50aEBnbWFpbC5jb20+iQFUBBMBCAA+AhsDBQsJCAcCBhUICQoLAgQW +AgMBAh4BAheAFiEEerPX9ZEXCIQnllE0Fbqtop2iDSYFAl1jj2EFCQeZ2E4ACgkQ +Fbqtop2iDSaTYwf+IY9XAGbjyDO8mNM1WE0kSpE+uXcWW98RPhm38TMjIX/0IUU8 +MOsARvCEkbXyqUMiOiuicx2BoflFvGutRyqQtI2sXSR/uCb1q3kO8t7RypC3vOok +iJAYXVUaZZb4EyYY67gmjf6i+SHmy8fSIOo2I+vlDf1Ii4eZyp45+XzDcReN35fr +bkXLUdC83Fqk70/74PhPqDwR3JwuVauV8GKHz3jRxdtebKbF7RoiUI6J5oWtkixH +ZDpwlzPVLdB8aMj7vDW72h/Z2UrDZu0inmQdiLPeHy2NydXlDlm2xVviOMcCFY1O +CTiiD2vlgxWku3z5Nhcx+cX8VmySGWJqGMBdkbkBDQRZjB4TAQgA4TBIlqcqoiPL +HESiHQCEU0DhfC7BTRL73SxS6gK4MmE0jtz27AA/+rchcUv3om4vVNw4dvkaRa0v +mhydMlaF+0Y/7gqTqaZSuXrl36nqw63B1l//Kgg7TKNX4X+LZ8hxqKj9xxocpbR1 +Qtb8h3TXb/aaWJU/o1TydvQXSOyH1w8R1S3PF9nrJJZb8BNrJ/A3SFqnvihFvLdN +qE7IfpHAIoaXW66e6V1FnF22c4a0D90qV/vMojGJO/mdrFLy3OwoOjAPFLJlnQDo +NlIXl9U7F7APJjGKuFJAa2QkdwXvcqRbc5GC120xL8ymuDQKp2K/rYRm/AN9IQ3X +xfR/kcNnGwARAQABiQE8BBgBCAAmAhsMFiEEerPX9ZEXCIQnllE0Fbqtop2iDSYF +Al1jj4cFCQeZ2HQACgkQFbqtop2iDSYcjAgAv19HsT/9MZI7xDkuzAWDxCAT5FDh +XgmPy9Bl/EFR83ETony7gpd+AA2GoDa/zd0js1Jz3YK0HnThKSRxyOIJ4CX3zgGW +nDT+T4oBxNwqmUH5eJ+2f09OhTXY9kcgTWoGFKWhmJi9uHzTOJDQ7ltDYOFBB6vY +kWrrHg62P3QGD6dgeOZlirtNYvAI6239fT+W8R4CaE17tiwK727nmncWX+11J7wf +h6XkQY6QbE1bHC7UG45HLJQvnTHu7C72W0aKfPZF5s8sALm31jmbVMfNbu8vzo5Z +o2WNAaw1TEseC+HCVwco7xJcy4Enr6WEFoKAeYiv5VUSVCb56IMSJTpK2Q== +=0Zw/ +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/roasbeef.asc b/scripts/keys/roasbeef.asc new file mode 100644 index 000000000..e1227808e --- /dev/null +++ b/scripts/keys/roasbeef.asc @@ -0,0 +1,109 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=4c8j +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/keys/wpaulino.asc b/scripts/keys/wpaulino.asc new file mode 100644 index 000000000..5c02c8a95 --- /dev/null +++ b/scripts/keys/wpaulino.asc @@ -0,0 +1,109 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=muRS +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index f1ba638fc..943113c9f 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -11,17 +11,23 @@ HEADER_JSON="Accept: application/json" HEADER_GH_JSON="Accept: application/vnd.github.v3+json" MIN_REQUIRED_SIGNATURES=5 -# All keys that can sign lnd releases. The key must be downloadable/importable -# from the URL given after the space. +# All keys that can sign lnd releases. The key must be added as a file to the +# keys directory, for example: scripts/keys/.asc +# The username in the key file must match the username used for signing a +# manifest (manifest--v0.xx.yy-beta.sig), otherwise the signature +# won't be counted. +# NOTE: Reviewers of this file must make sure that both the key IDs and +# usernames in the list below are unique! KEYS=() -KEYS+=("F4FC70F07310028424EFC20A8E4256593F177720 https://keybase.io/guggero/pgp_keys.asc") -KEYS+=("15E7ECF257098A4EF91655EB4CA7FE54A6213C91 https://keybase.io/carlakirkcohen/pgp_keys.asc") -KEYS+=("9C8D61868A7C492003B2744EE7D737B67FA592C7 https://keybase.io/bitconner/pgp_keys.asc") -KEYS+=("E4D85299674B2D31FAA1892E372CBD7633C61696 https://keybase.io/roasbeef/pgp_keys.asc") -KEYS+=("729E9D9D92C75A5FBFEEE057B5DD717BEF7CA5B1 https://keybase.io/wpaulino/pgp_keys.asc") -KEYS+=("7E81EF6B9989A9CC93884803118759E83439A9B1 https://keybase.io/eugene_/pgp_keys.asc") -KEYS+=("7AB3D7F5911708842796513415BAADA29DA20D26 https://keybase.io/halseth/pgp_keys.asc") -KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 https://keybase.io/arshbot/pgp_keys.asc") +KEYS+=("F4FC70F07310028424EFC20A8E4256593F177720 guggero") +KEYS+=("15E7ECF257098A4EF91655EB4CA7FE54A6213C91 carlaKC") +KEYS+=("9C8D61868A7C492003B2744EE7D737B67FA592C7 cfromknecht") +KEYS+=("E4D85299674B2D31FAA1892E372CBD7633C61696 roasbeef") +KEYS+=("729E9D9D92C75A5FBFEEE057B5DD717BEF7CA5B1 wpaulino") +KEYS+=("7E81EF6B9989A9CC93884803118759E83439A9B1 Crypt-iQ") +KEYS+=("7AB3D7F5911708842796513415BAADA29DA20D26 halseth") +KEYS+=("9FC6B0BFD597A94DBF09708280E5375C094198D8 bhandras") +KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 arshbot") TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX) @@ -43,16 +49,42 @@ function verify_version() { } function import_keys() { + # A trick to get the absolute directory where this script is located, no + # matter how or from where it was called. We'll need it to locate the key + # files which are located relative to this script. + DIR="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" + + # Import all the signing keys. We'll create a key ring for each user and use + # that exact key ring when verifying a user's signature. That way we can make + # sure one user cannot just upload multiple signatures to reach the 5/7 + # required sigs. for key in "${KEYS[@]}"; do KEY_ID=$(echo $key | cut -d' ' -f1) - IMPORT_URL=$(echo $key | cut -d' ' -f2) - echo "Downloading and importing key $KEY_ID from $IMPORT_URL" - curl -L -s $IMPORT_URL | gpg --import + USERNAME=$(echo $key | cut -d' ' -f2) + IMPORT_FILE="keys/$USERNAME.asc" + KEY_FILE="$DIR/$IMPORT_FILE" + KEYRING_UNTRUSTED="$TEMP_DIR/$USERNAME.pgp-untrusted" + KEYRING_TRUSTED="$TEMP_DIR/$USERNAME.pgp" + + # Because a key file could contain multiple keys, we need to be careful. To + # make sure we only import and use the key with the hard coded key ID of + # this script, we first import the file into a temporary untrusted keyring + # and then only export the specific key with the given ID into our final, + # trusted keyring that we later use for verification. This is exactly what + # https://github.com/Kixunil/sqck does but we didn't want to add another + # binary dependency to this script so we re-implemented it in the following + # few lines. + echo "" + echo "Importing key(s) from $KEY_FILE into temporary keyring $KEYRING_UNTRUSTED" + gpg --no-default-keyring --keyring "$KEYRING_UNTRUSTED" \ + --import < "$KEY_FILE" + + echo "" + echo "Exporting key $KEY_ID from untrusted keyring to trusted keyring $KEYRING_TRUSTED" + gpg --no-default-keyring --keyring "$KEYRING_UNTRUSTED" \ + --export "$KEY_ID" | \ + gpg --no-default-keyring --keyring "$KEYRING_TRUSTED" --import - # Make sure we actually imported the correct key. - if ! gpg --list-key "$KEY_ID"; then - echo "ERROR: Imported key from $IMPORT_URL doesn't match ID $KEY_ID." - fi done } From c8987ec2c582b161ccf6d6c39fecd643cd254caf Mon Sep 17 00:00:00 2001 From: positiveblue Date: Mon, 27 Sep 2021 11:03:09 +0200 Subject: [PATCH 06/12] scripts: add positiveblue key to verify script --- scripts/keys/positiveblue.asc | 110 ++++++++++++++++++++++++++++++++++ scripts/verify-install.sh | 1 + 2 files changed, 111 insertions(+) create mode 100644 scripts/keys/positiveblue.asc diff --git a/scripts/keys/positiveblue.asc b/scripts/keys/positiveblue.asc new file mode 100644 index 000000000..3ad403baf --- /dev/null +++ b/scripts/keys/positiveblue.asc @@ -0,0 +1,110 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +dlwIwA== +=aC9Q +-----END PGP PUBLIC KEY BLOCK----- diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index 943113c9f..e347a4005 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -28,6 +28,7 @@ KEYS+=("7E81EF6B9989A9CC93884803118759E83439A9B1 Crypt-iQ") KEYS+=("7AB3D7F5911708842796513415BAADA29DA20D26 halseth") KEYS+=("9FC6B0BFD597A94DBF09708280E5375C094198D8 bhandras") KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 arshbot") +KEYS+=("EB13A98091E8D67CDD7FC5A7E9FE7FE00AD163A4 positiveblue") TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX) From 0984638a74e533e834711be42a783d74b064f9af Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:11 +0200 Subject: [PATCH 07/12] scripts: make sure signature files have unique names To fix a simple attack where the same file would be uploaded multiple times under the same name, we make sure we only count unique file names. --- scripts/verify-install.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index e347a4005..6527b464d 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -103,6 +103,11 @@ function verify_signatures() { MANIFEST=$(echo $ASSETS | jq -r "$MANIFEST_SELECTOR") SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR") + # We need to make sure we have unique signature file names. Otherwise someone + # could just upload the same signature multiple times (if GH allows it for + # some reason). + SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR" | sort | uniq) + # Download the main "manifest-*.txt" and all "manifest-*.sig" files containing # the detached signatures. echo "Downloading $MANIFEST" From 6d0368a1897b1e11937a4a984907d161b364e641 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:12 +0200 Subject: [PATCH 08/12] scripts: pin signatures to keys With this commit we add a new restriction that checks that the username in the signature file (manifest--.sig) actually does have a signing key and that the signature was created with that key. The signature is only counted towards the minimum of 5 signatures if that check is successful. The changes in this commit were inspired by @kixunil in #5048. --- scripts/verify-install.sh | 58 +++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index 6527b464d..fc100c4c0 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -105,7 +105,9 @@ function verify_signatures() { # We need to make sure we have unique signature file names. Otherwise someone # could just upload the same signature multiple times (if GH allows it for - # some reason). + # some reason). Just adding the same files under different names also won't + # work because we parse the signing user's name from the file. If a random + # username is chosen then a signing key won't be found for it. SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR" | sort | uniq) # Download the main "manifest-*.txt" and all "manifest-*.sig" files containing @@ -120,17 +122,54 @@ function verify_signatures() { echo "" - # Before we even look at the content of the manifest, we first want to make - # sure the signatures actually sign that exact manifest. + # Before we even look at the content of the manifest, we first want to make sure + # the signatures actually sign that exact manifest. NUM_CHECKS=0 for signature in $SIGNATURES; do - echo "Verifying $signature" - if gpg --verify "$TEMP_DIR/$signature" "$TEMP_DIR/$MANIFEST" 2>&1 | grep -q "Good signature"; then - echo "Signature for $signature appears valid: " - gpg --verify "$TEMP_DIR/$signature" "$TEMP_DIR/$MANIFEST" 2>&1 | grep "using" - elif gpg --verify "$TEMP_DIR/$signature" 2>&1 | grep -q "No public key"; then - echo "Unable to verify signature $signature, no key available, skipping" + # Remove everything from the filename after the username. We start with + # "manifest-USERNAME-v0.xx.yy-beta.sig" and have "manifest-USERNAME" after + # this step. + USERNAME=${signature%-$VERSION.sig} + + # Remove the manifest- part before the username. + USERNAME=${USERNAME##manifest-} + + # If the user is known, they should have a key ring file with only their key. + KEYRING="$TEMP_DIR/$USERNAME.pgp" + if [[ ! -f "$KEYRING" ]]; then + echo "User $USERNAME does not have a known key, skipping" continue + fi + + # We'll write the status of the verification to a special file that we can + # then inspect. + STATUS_FILE="$TEMP_DIR/$USERNAME.sign-status" + + # Make sure we haven't yet tried to verify a signature for that user. + if [[ -f "$STATUS_FILE" ]]; then + echo "ERROR: A signature for user $USERNAME was already verified!" + echo " Either file name $signature is wrong or multiple files of same " + echo " user were uploaded." + exit 1 + fi + + # Run the actual verification. + gpg --no-default-keyring --keyring "$KEYRING" --status-fd=1 \ + --verify "$TEMP_DIR/$signature" "$TEMP_DIR/$MANIFEST" \ + > "$STATUS_FILE" 2>&1 || { echo "ERROR: Invalid signature!"; exit 1; } + + echo "Verifying $signature of user $USERNAME against key ring $KEYRING" + if grep -q "Good signature" "$STATUS_FILE"; then + echo "Signature for $signature appears valid: " + grep "VALIDSIG" "$STATUS_FILE" + elif grep -q "No public key" "$STATUS_FILE"; then + # Because we checked above if the user has a key, getting the "No public + # key" error now means the key used for signing doesn't match the key we + # have in our repo and is now a failure case. + echo "ERROR: Unable to verify signature $signature, no key available" + echo " The signature $signature was signed with a different key than was" + echo " imported for user $USERNAME." + exit 1 else echo "ERROR: Did not get valid signature for $MANIFEST in $signature!" echo " The developer signature $signature disagrees on the expected" @@ -140,6 +179,7 @@ function verify_signatures() { fi echo "Verified $signature against $MANIFEST" + echo "" ((NUM_CHECKS=NUM_CHECKS+1)) done From 5afed8ab623c4e5d5223c5764c0b586ce1a575b8 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:13 +0200 Subject: [PATCH 09/12] docker: add keys to docker image Because the PGP keys are no longer downloaded from Keybase but are used from the repo directly, we also have to copy them to the Docker image so we can run the script without needing to supply them through a volume. --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index c6310f5c6..ae73313c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,6 +44,7 @@ RUN apk --no-cache add \ COPY --from=builder /go/bin/lncli /bin/ COPY --from=builder /go/bin/lnd /bin/ COPY --from=builder /go/src/github.com/lightningnetwork/lnd/scripts/verify-install.sh / +COPY --from=builder /go/src/github.com/lightningnetwork/lnd/scripts/keys/* /keys/ # Store the SHA256 hash of the binaries that were just produced for later # verification. From 5bafff2cf24c94306fe9b9bb5cac440270743c0d Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:15 +0200 Subject: [PATCH 10/12] scripts: allow packaged release archive to be verified Instead of only allowing to verify installed/unpacked binaries, we also allow a single binary or packaged release archive to be verified. --- scripts/verify-install.sh | 51 +++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index fc100c4c0..27172a35c 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -247,7 +247,7 @@ LNCLI_BIN=$(which lncli) if [[ $# -eq 0 ]]; then echo "ERROR: missing expected version!" - echo "Usage: verify-install.sh expected-version [path-to-lnd-binary path-to-lncli-binary]" + echo "Usage: verify-install.sh expected-version [path-to-lnd-binary-or-download-archive [path-to-lncli-binary]]" exit 1 fi @@ -258,12 +258,19 @@ shift # Verify that the expected version is well-formed. verify_version "$VERSION" +# Make sure we have all tools needed for the verification. +check_command curl +check_command jq +check_command gpg + # If exactly two parameters are specified, we expect the first one to be lnd and -# the second one to be lncli. +# the second one to be lncli. One parameter is either just a single binary or a +# packaged release archive. No parameters means picking up lnd and lncli from +# the system path. if [[ $# -eq 2 ]]; then LND_BIN=$(realpath $1) LNCLI_BIN=$(realpath $2) - + # Make sure both files actually exist. if [[ ! -f $LND_BIN ]]; then echo "ERROR: $LND_BIN not found!" @@ -273,24 +280,30 @@ if [[ $# -eq 2 ]]; then echo "ERROR: $LNCLI_BIN not found!" exit 1 fi + + # Make sure both binaries can be found and are executable. + check_command "$LND_BIN" + check_command "$LNCLI_BIN" + +elif [[ $# -eq 1 ]]; then + # We're verifying a single binary or a packaged release archive. + PACKAGE_BIN=$(realpath $1) + elif [[ $# -eq 0 ]]; then # By default we're picking up lnd and lncli from the system $PATH. LND_BIN=$(which lnd) LNCLI_BIN=$(which lncli) + + # Make sure both binaries can be found and are executable. + check_command "$LND_BIN" + check_command "$LNCLI_BIN" + else echo "ERROR: invalid number of parameters!" echo "Usage: verify-install.sh [lnd-binary lncli-binary]" exit 1 fi -# Make sure both binaries can be found and are executable. -check_command "$LND_BIN" -check_command "$LNCLI_BIN" - -check_command curl -check_command jq -check_command gpg - # Import all the signing keys. import_keys @@ -301,8 +314,16 @@ verify_signatures # Then make sure that the hash of the installed binaries can be found in the # manifest that we now have verified the signatures for. -check_hash "$LND_BIN" "lnd" -check_hash "$LNCLI_BIN" "lncli" +if [[ "$PACKAGE_BIN" != "" ]]; then + check_hash "$PACKAGE_BIN" "$PACKAGE_BIN" -echo "" -echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers." + echo "" + echo "SUCCESS! Verified $PACKAGE_BIN against $MANIFEST signed by $NUM_CHECKS developers." + +else + check_hash "$LND_BIN" "lnd" + check_hash "$LNCLI_BIN" "lncli" + + echo "" + echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers." +fi From d7d1574095206f1fe0ad88959535ea5ba5614b89 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:03:16 +0200 Subject: [PATCH 11/12] scripts: verify version in manifest To make a downgrade attack harder, we also check that the version string is contained in the manifest, on the same line as the hash. --- scripts/verify-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index 27172a35c..98c2db824 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -231,7 +231,7 @@ function check_hash() { fi fi - if ! grep -q "^$SUM" "$TEMP_DIR/$MANIFEST"; then + if ! grep "^$SUM" "$TEMP_DIR/$MANIFEST" | grep -q "$VERSION"; then echo "ERROR: Hash $SUM for $2 not found in $MANIFEST: " cat "$TEMP_DIR/$MANIFEST" echo " The expected release binaries have been verified with the developer " From 421add062cd8be91f3f96ea621f7445eb0cf99e4 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 27 Sep 2021 11:21:42 +0200 Subject: [PATCH 12/12] docs: add release notes --- docs/release-notes/release-notes-0.14.0.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/release-notes/release-notes-0.14.0.md b/docs/release-notes/release-notes-0.14.0.md index fd7941c8f..d94b6de72 100644 --- a/docs/release-notes/release-notes-0.14.0.md +++ b/docs/release-notes/release-notes-0.14.0.md @@ -142,6 +142,13 @@ documentation](../psbt.md#use-the-batchopenchannel-rpc-for-safe-batch-channel-fu ## Security +* The release signature verification script [was overhauled to fix some possible + attack vectors and user + errors](https://github.com/lightningnetwork/lnd/pull/5053). The public keys + used to verify the signatures against are no longer downloaded form Keybase + but instead are kept in the `lnd` git repository. This allows for a more + transparent way of keeping track of changes to the signing keys. + ### Admin macaroon permissions The default file permissions of admin.macaroon were [changed from 0600 to