mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 01:36:24 +01:00
scripts: extract functions
As a preparation to make the script easier to understand, we extract some of the sub tasks into functions.
This commit is contained in:
parent
23d7065655
commit
4c8bf9c28d
1 changed files with 109 additions and 108 deletions
|
@ -9,6 +9,7 @@ MANIFEST_SELECTOR=". | select(.name | test(\"manifest-v.*(\\\\.txt)$\")) | .name
|
||||||
SIGNATURE_SELECTOR=". | select(.name | test(\"manifest-.*(\\\\.sig)$\")) | .name"
|
SIGNATURE_SELECTOR=". | select(.name | test(\"manifest-.*(\\\\.sig)$\")) | .name"
|
||||||
HEADER_JSON="Accept: application/json"
|
HEADER_JSON="Accept: application/json"
|
||||||
HEADER_GH_JSON="Accept: application/vnd.github.v3+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
|
# All keys that can sign lnd releases. The key must be downloadable/importable
|
||||||
# from the URL given after the space.
|
# 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+=("7AB3D7F5911708842796513415BAADA29DA20D26 https://keybase.io/halseth/pgp_keys.asc")
|
||||||
KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 https://keybase.io/arshbot/pgp_keys.asc")
|
KEYS+=("E97A1AB6C77A1D2B72F50A6F90E00CCB1C74C611 https://keybase.io/arshbot/pgp_keys.asc")
|
||||||
|
|
||||||
|
TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX)
|
||||||
|
|
||||||
function check_command() {
|
function check_command() {
|
||||||
echo -n "Checking if $1 is installed... "
|
echo -n "Checking if $1 is installed... "
|
||||||
if ! command -v "$1"; then
|
if ! command -v "$1"; then
|
||||||
|
@ -30,6 +33,107 @@ function check_command() {
|
||||||
fi
|
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.
|
# By default we're picking up lnd and lncli from the system $PATH.
|
||||||
LND_BIN=$(which lnd)
|
LND_BIN=$(which lnd)
|
||||||
LNCLI_BIN=$(which lncli)
|
LNCLI_BIN=$(which lncli)
|
||||||
|
@ -104,121 +208,18 @@ if [[ ${#LNCLI_SUM} -ne 64 ]]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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.
|
# Import all the signing keys.
|
||||||
for key in "${KEYS[@]}"; do
|
import_keys
|
||||||
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
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Download the JSON of the release itself. That'll contain the release ID we need for the next call.
|
# Verify and count the signatures.
|
||||||
RELEASE_JSON=$(curl -L -s -H "$HEADER_JSON" "$RELEASE_URL/$LND_VERSION")
|
verify_signatures
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# Then make sure that the hash of the installed binaries can be found in the
|
# Then make sure that the hash of the installed binaries can be found in the
|
||||||
# manifest that we now have verified the signatures for.
|
# manifest that we now have verified the signatures for.
|
||||||
if ! grep -q "^$LND_SUM" "$MANIFEST"; then
|
check_hash "$LND_SUM" "lnd"
|
||||||
echo "ERROR: Hash $LND_SUM for lnd not found in $MANIFEST: "
|
check_hash "$LNCLI_SUM" "lncli"
|
||||||
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
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers."
|
echo "SUCCESS! Verified lnd and lncli against $MANIFEST signed by $NUM_CHECKS developers."
|
||||||
|
|
Loading…
Add table
Reference in a new issue