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.
This commit is contained in:
parent
132d23c964
commit
99ba272822
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
@ -73,10 +73,10 @@ jobs:
|
|||||||
curl https://keybase.io/roasbeef/pgp_keys.asc | gpg --import
|
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:
|
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:
|
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.
|
Alternatively, [the open timestamps website](https://opentimestamps.org/) can be used to verify timestamps if one doesn't have a `bitcoind` instance accessible locally.
|
||||||
|
@ -99,11 +99,11 @@ script in the image that can be called (before starting the container for
|
|||||||
example):
|
example):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ docker pull lightninglabs/lnd:v0.12.0-beta
|
⛰ docker pull lightninglabs/lnd:v0.12.0-beta
|
||||||
$ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh
|
⛰ docker run --rm --entrypoint="" lightninglabs/lnd:v0.12.0-beta /verify-install.sh
|
||||||
$ OK=$?
|
⛰ OK=$?
|
||||||
$ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done
|
⛰ if [ "$OK" -ne "0" ]; then echo "Verification failed!"; exit 1; done
|
||||||
$ docker run lightninglabs/lnd [command-line options]
|
⛰ docker run lightninglabs/lnd [command-line options]
|
||||||
```
|
```
|
||||||
|
|
||||||
# Signing an Existing Manifest File
|
# Signing an Existing Manifest File
|
||||||
@ -121,8 +121,6 @@ signature during signing.
|
|||||||
|
|
||||||
Assuming `USERNAME` is your current nick as a developer, then the following
|
Assuming `USERNAME` is your current nick as a developer, then the following
|
||||||
command will generate a proper signature:
|
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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@ PROJECT=lnd
|
|||||||
|
|
||||||
RELEASE_URL=https://github.com/$REPO/$PROJECT/releases
|
RELEASE_URL=https://github.com/$REPO/$PROJECT/releases
|
||||||
API_URL=https://api.github.com/repos/$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_JSON="Accept: application/json"
|
||||||
HEADER_GH_JSON="Accept: application/vnd.github.v3+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')
|
RELEASE_ID=$(echo $RELEASE_JSON | jq -r '.id')
|
||||||
echo "Release $TAG_NAME found with ID $RELEASE_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[]')
|
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")
|
SIGNATURES=$(echo $ASSETS | jq -r "$SIGNATURE_SELECTOR")
|
||||||
|
|
||||||
# Download all "manifest-*.txt.asc" as those contain both the hashes that were
|
# Download the main "manifest-*.txt" and all "manifest-*.sig" files containing
|
||||||
# signed and the signature itself (=detached sig).
|
# the detached signatures.
|
||||||
TEMP_DIR=$(mktemp -d /tmp/lnd-sig-verification-XXXXXX)
|
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
|
for signature in $SIGNATURES; do
|
||||||
echo "Downloading $signature"
|
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/$LND_VERSION/$signature"
|
||||||
@ -144,13 +149,14 @@ done
|
|||||||
echo ""
|
echo ""
|
||||||
cd $TEMP_DIR || exit 1
|
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
|
NUM_CHECKS=0
|
||||||
for signature in $SIGNATURES; do
|
for signature in $SIGNATURES; do
|
||||||
# First make sure the downloaded signature file is valid.
|
|
||||||
echo "Verifying $signature"
|
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: "
|
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
|
elif gpg --verify "$signature" 2>&1 | grep -q "No public key"; then
|
||||||
echo "Unable to verify signature $signature, no key available, skipping"
|
echo "Unable to verify signature $signature, no key available, skipping"
|
||||||
continue
|
continue
|
||||||
@ -159,32 +165,33 @@ for signature in $SIGNATURES; do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo "Verified $signature against $MANIFEST"
|
||||||
|
|
||||||
# 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"
|
|
||||||
((NUM_CHECKS=NUM_CHECKS+1))
|
((NUM_CHECKS=NUM_CHECKS+1))
|
||||||
done
|
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
|
# 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
|
# installed. If we arrive here without exiting, it means no signature manifests
|
||||||
# were uploaded (yet) with the correct naming pattern.
|
# were uploaded (yet) with the correct naming pattern.
|
||||||
if [[ $NUM_CHECKS -lt 1 ]]; then
|
if [[ $NUM_CHECKS -lt 1 ]]; then
|
||||||
echo "ERROR: No valid signatures found!"
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user