diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 704f406e..0f40d520 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -73,10 +73,10 @@ jobs: curl https://keybase.io/roasbeef/pgp_keys.asc | gpg --import ``` - Once you have the required PGP keys, you can verify the release (assuming `manifest-roasbeef-${{ env.RELEASE_VERSION }}.txt.asc` is in the current directory) with: + Once you have the required PGP keys, you can verify the release (assuming `manifest-roasbeef-${{ env.RELEASE_VERSION }}.sig` and `manifest-${{ env.RELEASE_VERSION }}.txt` are in the current directory) with: ``` - gpg --verify manifest-roasbeef-${{ env.RELEASE_VERSION }}.txt.asc + gpg --verify manifest-roasbeef-${{ env.RELEASE_VERSION }}.sig manifest-${{ env.RELEASE_VERSION }}.txt ``` You should see the following if the verification was successful: @@ -95,7 +95,7 @@ jobs: Assuming you have the opentimestamps client installed locally, the timestamps can be verified with the following commands: ``` - ots verify manifest-roasbeef-${{ env.RELEASE_VERSION }}.txt.asc.ots -f manifest-roasbeef-${{ env.RELEASE_VERSION }}.txt.asc + ots verify manifest-roasbeef-${{ env.RELEASE_VERSION }}.sig.ots -f manifest-roasbeef-${{ env.RELEASE_VERSION }}.sig ``` Alternatively, [the open timestamps website](https://opentimestamps.org/) can be used to verify timestamps if one doesn't have a `bitcoind` instance accessible locally. diff --git a/docs/release.md b/docs/release.md index 8b364fda..42f2b8df 100644 --- a/docs/release.md +++ b/docs/release.md @@ -99,11 +99,11 @@ 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 -$ docker run lightninglabs/lnd [command-line options] +⛰ 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 +⛰ docker run lightninglabs/lnd [command-line options] ``` # Signing an Existing Manifest File @@ -121,8 +121,6 @@ signature during signing. Assuming `USERNAME` is your current nick as a developer, then the following command will generate a proper signature: +```shell +⛰ gpg --detach-sig --output manifest-USERNAME-TAG.sig manifest-TAG.txt ``` -gpg --detach-sig --output manifest-USERNAME-TAG.txt.asc --clear-sign manifest-TAG.txt -``` - - diff --git a/scripts/verify-install.sh b/scripts/verify-install.sh index cf5f9ad3..2bdd18c5 100755 --- a/scripts/verify-install.sh +++ b/scripts/verify-install.sh @@ -5,7 +5,8 @@ PROJECT=lnd RELEASE_URL=https://github.com/$REPO/$PROJECT/releases API_URL=https://api.github.com/repos/$REPO/$PROJECT/releases -SIGNATURE_SELECTOR=". | select(.name | test(\"manifest-.*(\\\\.txt\\\\.asc)$\")) | .name" +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" @@ -129,13 +130,17 @@ 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 manifests and signatures. +# 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 all "manifest-*.txt.asc" as those contain both the hashes that were -# signed and the signature itself (=detached sig). +# 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" @@ -144,13 +149,14 @@ 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 - # First make sure the downloaded signature file is valid. echo "Verifying $signature" - if gpg --verify "$signature" 2>&1 | grep -q "Good signature"; then + if gpg --verify "$signature" "$MANIFEST" 2>&1 | grep -q "Good signature"; then echo "Signature for $signature checks out: " - gpg --verify "$signature" 2>&1 | grep "using" + 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 @@ -159,32 +165,33 @@ for signature in $SIGNATURES; do exit 1 fi - echo "" - - # Then make sure that the hash of the installed binaries can be found in the - # signed list of hashes. - if ! grep -q "$LND_SUM" "$signature"; then - echo "ERROR: Hash $LND_SUM for lnd not found in $signature: " - cat "$signature" - exit 1 - fi - - if ! grep -q "$LNCLI_SUM" "$signature"; then - echo "ERROR: Hash $LNCLI_SUM for lncli not found in $signature: " - cat "$signature" - exit 1 - fi - - echo "Verified lnd and lncli hashes against $signature" + echo "Verified $signature against $MANIFEST" ((NUM_CHECKS=NUM_CHECKS+1)) done +# 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" + exit 1 +fi + +if ! grep -q "^$LNCLI_SUM" "$MANIFEST"; then + echo "ERROR: Hash $LNCLI_SUM for lncli not found in $MANIFEST: " + cat "$MANIFEST" + exit 1 +fi + +echo "" +echo "Verified lnd and lncli hashes against $MANIFEST" + # We want at least one signature that signs 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 1 ]]; then echo "ERROR: No valid signatures found!" - echo "Make sure the release $LND_VERSION contains any signed manifests." + echo "Make sure the release $LND_VERSION contains any signatures for the manifest." exit 1 fi