76 lines
1.8 KiB
Bash
Executable File
76 lines
1.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# verify-signature.sh — verify a release binary signature against any trusted public key
|
|
#
|
|
# Usage:
|
|
# sh scripts/verify-signature.sh <binary-path>
|
|
#
|
|
# Verifies <binary-path>.sig against all keys in developers/*.pub
|
|
# Exits 0 if any key matches, 1 if none match.
|
|
#
|
|
# Requirements: openssl 3.x, python3 (for base64 decode)
|
|
|
|
set -e
|
|
|
|
BINARY="$1"
|
|
SIG_PATH="${BINARY}.sig"
|
|
KEYS_DIR="$(dirname "$0")/../developers"
|
|
|
|
if [ -z "$BINARY" ]; then
|
|
echo "Usage: sh scripts/verify-signature.sh <binary-path>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$BINARY" ]; then
|
|
echo "Binary not found: $BINARY" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$SIG_PATH" ]; then
|
|
echo "Signature not found: $SIG_PATH" >&2
|
|
exit 1
|
|
fi
|
|
|
|
MATCHED=""
|
|
|
|
for PUBFILE in "$KEYS_DIR"/*.pub; do
|
|
[ -f "$PUBFILE" ] || continue
|
|
NAME=$(basename "$PUBFILE" .pub)
|
|
|
|
# Decode base64 raw public key → DER SubjectPublicKeyInfo wrapper
|
|
# Ed25519 DER prefix: 302a300506032b6570032100
|
|
RAW_B64=$(cat "$PUBFILE")
|
|
PEM_PATH="/tmp/verify-${NAME}.pem"
|
|
|
|
python3 - "$RAW_B64" "$PEM_PATH" <<'PYEOF'
|
|
import sys, base64, binascii
|
|
raw = base64.b64decode(sys.argv[1])
|
|
prefix = bytes.fromhex("302a300506032b6570032100")
|
|
der = prefix + raw
|
|
b64 = base64.b64encode(der).decode()
|
|
with open(sys.argv[2], "w") as f:
|
|
f.write("-----BEGIN PUBLIC KEY-----\n")
|
|
for i in range(0, len(b64), 64):
|
|
f.write(b64[i:i+64] + "\n")
|
|
f.write("-----END PUBLIC KEY-----\n")
|
|
PYEOF
|
|
|
|
if openssl pkeyutl -verify \
|
|
-pubin -inkey "$PEM_PATH" \
|
|
-rawin \
|
|
-in "$BINARY" \
|
|
-sigfile "$SIG_PATH" \
|
|
2>/dev/null; then
|
|
echo "OK: signature verified by key '$NAME'"
|
|
MATCHED="$NAME"
|
|
rm -f "$PEM_PATH"
|
|
break
|
|
fi
|
|
|
|
rm -f "$PEM_PATH"
|
|
done
|
|
|
|
if [ -z "$MATCHED" ]; then
|
|
echo "FAIL: signature does not match any trusted key in developers/" >&2
|
|
exit 1
|
|
fi
|