upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/scripts/verify-release.sh
blob: c651e7807ce00a750439760997e143db71b66b61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env bash
set -euo pipefail

repo="bitflash-coin/bitflash"
tag="${1:-latest}"
require_signature=0

usage() {
  cat <<'EOF'
Usage: scripts/verify-release.sh [tag|latest] [--require-signature]

Downloads the release checksum file and every asset named in it, then verifies:
  1. SHA256SUMS.asc, if present, against SHA256SUMS with gpg.
  2. SHA256SUMS against the downloaded assets.

Use --require-signature for release audits. Without it, older releases that
ship only SHA256SUMS are checked for integrity and reported as unsigned.
EOF
}

for arg in "${@:2}"; do
  case "$arg" in
    --require-signature) require_signature=1 ;;
    -h|--help) usage; exit 0 ;;
    *) echo "unknown option: $arg" >&2; usage >&2; exit 2 ;;
  esac
done

if [ "$tag" = "-h" ] || [ "$tag" = "--help" ]; then
  usage
  exit 0
fi

need() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "missing required command: $1" >&2
    exit 1
  fi
}

need sed
need awk

if command -v sha256sum >/dev/null 2>&1; then
  sha_check=(sha256sum -c SHA256SUMS)
elif command -v shasum >/dev/null 2>&1; then
  sha_check=(shasum -a 256 -c SHA256SUMS)
else
  echo "missing required command: sha256sum or shasum" >&2
  exit 1
fi

download() {
  local url="$1"
  local out="$2"
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$url" -o "$out"
  elif command -v wget >/dev/null 2>&1; then
    wget -q "$url" -O "$out"
  else
    echo "missing required command: curl or wget" >&2
    exit 1
  fi
}

if [ "$tag" = "latest" ]; then
  tag="$(download "https://api.github.com/repos/$repo/releases/latest" - |
    sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' |
    head -1)"
  if [ -z "$tag" ]; then
    echo "could not resolve latest release tag" >&2
    exit 1
  fi
fi

workdir="$(mktemp -d "${TMPDIR:-/tmp}/bitflash-release-verify.XXXXXX")"
cleanup() { rm -rf "$workdir"; }
trap cleanup EXIT

base_url="https://github.com/$repo/releases/download/$tag"

echo "Verifying Bitflash $tag"
echo "Working directory: $workdir"
cd "$workdir"

download "$base_url/SHA256SUMS" SHA256SUMS

if download "$base_url/SHA256SUMS.asc" SHA256SUMS.asc 2>/dev/null; then
  if ! command -v gpg >/dev/null 2>&1; then
    echo "SHA256SUMS.asc exists, but gpg is not installed" >&2
    exit 1
  fi
  gpg --verify SHA256SUMS.asc SHA256SUMS
  echo "Signature OK"
else
  if [ "$require_signature" -eq 1 ]; then
    echo "release does not publish SHA256SUMS.asc" >&2
    exit 1
  fi
  echo "WARNING: no SHA256SUMS.asc found; checking hashes only"
fi

awk '{print $2}' SHA256SUMS | while IFS= read -r file; do
  file="${file#\*}"
  file="${file#./}"
  [ -z "$file" ] && continue
  case "$file" in
    */*|..*) echo "refusing unexpected checksum path: $file" >&2; exit 1 ;;
  esac
  echo "Downloading $file"
  download "$base_url/$file" "$file"
done

"${sha_check[@]}"
echo "Release assets OK"