Merge pull request #5019 from guggero/detach-sign
release: create and verify detached signatures, fix hashing command on MacOS
This commit is contained in:
commit
12182d0fc9
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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ function build_release() {
|
|||||||
|
|
||||||
# Add the hashes for the individual binaries as well for easy verification
|
# Add the hashes for the individual binaries as well for easy verification
|
||||||
# of a single installed binary.
|
# of a single installed binary.
|
||||||
sha256sum "${dir}/"* >> "manifest-$tag.txt"
|
shasum -a 256 "${dir}/"* >> "manifest-$tag.txt"
|
||||||
|
|
||||||
if [[ $os == "windows" ]]; then
|
if [[ $os == "windows" ]]; then
|
||||||
reproducible_zip "${dir}"
|
reproducible_zip "${dir}"
|
||||||
@ -193,7 +193,7 @@ function build_release() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Add the hash of the packages too, then sort by the second column (name).
|
# Add the hash of the packages too, then sort by the second column (name).
|
||||||
sha256sum lnd-* vendor* >> "manifest-$tag.txt"
|
shasum -a 256 lnd-* vendor* >> "manifest-$tag.txt"
|
||||||
LC_ALL=C sort -k2 -o "manifest-$tag.txt" "manifest-$tag.txt"
|
LC_ALL=C sort -k2 -o "manifest-$tag.txt" "manifest-$tag.txt"
|
||||||
cat "manifest-$tag.txt"
|
cat "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"
|
||||||
|
|
||||||
@ -63,8 +64,8 @@ check_command gpg
|
|||||||
|
|
||||||
LND_VERSION=$($LND_BIN --version | cut -d'=' -f2)
|
LND_VERSION=$($LND_BIN --version | cut -d'=' -f2)
|
||||||
LNCLI_VERSION=$($LNCLI_BIN --version | cut -d'=' -f2)
|
LNCLI_VERSION=$($LNCLI_BIN --version | cut -d'=' -f2)
|
||||||
LND_SUM=$(sha256sum $LND_BIN | cut -d' ' -f1)
|
LND_SUM=$(shasum -a 256 $LND_BIN | cut -d' ' -f1)
|
||||||
LNCLI_SUM=$(sha256sum $LNCLI_BIN | cut -d' ' -f1)
|
LNCLI_SUM=$(shasum -a 256 $LNCLI_BIN | cut -d' ' -f1)
|
||||||
|
|
||||||
echo "Detected lnd $LND_BIN version $LND_VERSION with SHA256 sum $LND_SUM"
|
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"
|
echo "Detected lncli $LNCLI_BIN version $LNCLI_VERSION with SHA256 sum $LNCLI_SUM"
|
||||||
@ -81,6 +82,16 @@ if [[ ! "$LND_VERSION" =~ $version_regex ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
||||||
|
|
||||||
# If we're inside the docker image, there should be a shasums.txt file in the
|
# 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
|
# 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.
|
# the same hash as we did when building the image.
|
||||||
@ -119,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"
|
||||||
@ -134,49 +149,60 @@ 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 appears valid: "
|
||||||
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
|
||||||
else
|
else
|
||||||
echo "ERROR: Did not get valid signature for $signature!"
|
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
|
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"
|
||||||
|
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 "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
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "SUCCESS! Verified lnd and lncli against $NUM_CHECKS signature(s)."
|
echo "SUCCESS! Verified lnd and lncli against $NUM_CHECKS developer signature(s)."
|
||||||
|
Loading…
Reference in New Issue
Block a user