Browse Source

docs+scripts: switch to detached signatures

Due to a misunderstanding of how the gpg command line options work, we
didn't actually create detached signatures because the --clear-sign
flag would overwrite that. We update our verification script to now only
download the detached signatures and verify them against the main
manifest file.
We also update the signing instructions.
master
Oliver Gugger 3 years ago
parent
commit
99ba272822
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
  1. 6
      .github/workflows/release.yaml
  2. 16
      docs/release.md
  3. 55
      scripts/verify-install.sh

6
.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.

16
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
```

55
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 ""
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
# 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
# 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" "$signature"; then
echo "ERROR: Hash $LNCLI_SUM for lncli not found in $signature: "
cat "$signature"
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 "Verified lnd and lncli hashes against $signature"
((NUM_CHECKS=NUM_CHECKS+1))
done
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

Loading…
Cancel
Save