v29.4-roots.1 · Commit 7: [PATCH 07/13] release: establish Roots maintenance and assurance
ci/release/sign-manifest.sh
Before: /dev/null · After: ci/release/sign-manifest.sh
File metadata
new file mode 100755 index 0000000000000000000000000000000000000000..63c411e8460a5f1a317f247fe692d4a740990712
Download original patch · Release notes
Diff rows 1–65 of 65. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
ci/release/sign-manifest.sh
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Copyright (c) 2026-present The Bitcoin Roots developers
|
|
3
|
+
# Distributed under the MIT software license, see the accompanying
|
|
4
|
+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
5
|
+
|
|
6
|
+
export LC_ALL=C
|
|
7
|
+
set -Eeuo pipefail
|
|
8
|
+
|
|
9
|
+
if [[ "$#" -ne 3 ]]; then
|
|
10
|
+
printf 'Usage: %s MANIFEST PUBLIC_KEY_FILE EXPECTED_FINGERPRINT\n' "$0" >&2
|
|
11
|
+
exit 2
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
manifest=$1
|
|
15
|
+
public_key_file=$2
|
|
16
|
+
expected_fingerprint=$3
|
|
17
|
+
signature="${manifest}.asc"
|
|
18
|
+
|
|
19
|
+
if [[ ! -f "$manifest" ]]; then
|
|
20
|
+
printf 'Manifest does not exist: %s\n' "$manifest" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
if [[ -z "${BITCOIN_ROOTS_GPG_SK:-}" ]]; then
|
|
24
|
+
printf 'BITCOIN_ROOTS_GPG_SK is not configured; publishing an unsigned manifest\n' >&2
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
if [[ ! -f "$public_key_file" ]]; then
|
|
28
|
+
printf 'Public key does not exist: %s\n' "$public_key_file" >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
if [[ ! "$expected_fingerprint" =~ ^[0-9A-F]{40}$ ]]; then
|
|
32
|
+
printf 'Expected fingerprint must be 40 uppercase hexadecimal characters\n' >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
gpg_home="$(mktemp -d)"
|
|
37
|
+
cleanup() {
|
|
38
|
+
rm -rf -- "$gpg_home"
|
|
39
|
+
}
|
|
40
|
+
trap cleanup EXIT
|
|
41
|
+
chmod 0700 "$gpg_home"
|
|
42
|
+
export GNUPGHOME="$gpg_home"
|
|
43
|
+
|
|
44
|
+
public_fingerprint="$({
|
|
45
|
+
gpg --batch --with-colons --import-options show-only --import "$public_key_file" |
|
|
46
|
+
awk -F: '$1 == "fpr" { print $10; exit }'
|
|
47
|
+
})"
|
|
48
|
+
if [[ "$public_fingerprint" != "$expected_fingerprint" ]]; then
|
|
49
|
+
printf 'Unexpected release public-key fingerprint: %s\n' "$public_fingerprint" >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
printf '%s\n' "$BITCOIN_ROOTS_GPG_SK" | gpg --batch --import >/dev/null
|
|
54
|
+
secret_fingerprint="$({
|
|
55
|
+
gpg --batch --with-colons --list-secret-keys "$expected_fingerprint" |
|
|
56
|
+
awk -F: '$1 == "fpr" { print $10; exit }'
|
|
57
|
+
})"
|
|
58
|
+
if [[ "$secret_fingerprint" != "$expected_fingerprint" ]]; then
|
|
59
|
+
printf 'The configured secret key does not match the release public key\n' >&2
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
gpg --batch --yes --armor --local-user "$expected_fingerprint" \
|
|
64
|
+
--output "$signature" --detach-sign "$manifest"
|
|
65
|
+
gpg --batch --verify "$signature" "$manifest"
|