Skip to content

Commit d9c450f

Browse files
committed
Verify Tree-SHA512s in merge commits, enforce sigs are not SHA1
1 parent be908a6 commit d9c450f

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

contrib/verify-commits/gpg.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ VALID=false
88
REVSIG=false
99
IFS='
1010
'
11-
for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do
11+
if [ "$BITCOIN_VERIFY_COMMITS_ALLOW_SHA1" = 1 ]; then
12+
GPG_RES="$(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null)"
13+
else
14+
GPG_RES="$(echo "$INPUT" | gpg --trust-model always --weak-digest sha1 "$@" 2>/dev/null)"
15+
fi
16+
for LINE in $(echo "$GPG_RES"); do
1217
case "$LINE" in
1318
"[GNUPG:] VALIDSIG "*)
1419
while read KEY; do
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
b00ba6251f71fa1edaabdf809514e1bc3c67862e

contrib/verify-commits/verify-commits.sh

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,84 @@
99
DIR=$(dirname "$0")
1010
[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0")
1111

12+
echo "Using verify-commits data from ${DIR}"
13+
1214
VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root")
15+
VERIFIED_SHA512_ROOT=$(cat "${DIR}/trusted-sha512-root-commit")
1316
REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits")
1417

1518
HAVE_FAILED=false
1619
IS_SIGNED () {
1720
if [ $1 = $VERIFIED_ROOT ]; then
1821
return 0;
1922
fi
23+
24+
VERIFY_TREE=$2
25+
NO_SHA1=$3
26+
if [ $1 = $VERIFIED_SHA512_ROOT ]; then
27+
if [ "$VERIFY_TREE" = "1" ]; then
28+
echo "All Tree-SHA512s matched up to $VERIFIED_SHA512_ROOT" > /dev/stderr
29+
fi
30+
VERIFY_TREE=0
31+
NO_SHA1=0
32+
fi
33+
34+
if [ "$NO_SHA1" = "1" ]; then
35+
export BITCOIN_VERIFY_COMMITS_ALLOW_SHA1=0
36+
else
37+
export BITCOIN_VERIFY_COMMITS_ALLOW_SHA1=1
38+
fi
39+
2040
if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then
2141
export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1
2242
else
2343
export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0
2444
fi
45+
2546
if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then
2647
return 1;
2748
fi
49+
50+
if [ "$VERIFY_TREE" = 1 ]; then
51+
IFS_CACHE="$IFS"
52+
IFS='
53+
'
54+
for LINE in $(git ls-tree --full-tree -r $1); do
55+
case "$LINE" in
56+
"12"*)
57+
echo "Repo contains symlinks" > /dev/stderr
58+
IFS="$IFS_CACHE"
59+
return 1
60+
;;
61+
esac
62+
done
63+
IFS="$IFS_CACHE"
64+
65+
FILE_HASHES=""
66+
for FILE in $(git ls-tree --full-tree -r --name-only $1 | LANG=C sort); do
67+
HASH=$(git cat-file blob $1:"$FILE" | sha512sum | { read FIRST OTHER; echo $FIRST; } )
68+
[ "$FILE_HASHES" != "" ] && FILE_HASHES="$FILE_HASHES"$'\n'
69+
FILE_HASHES="$FILE_HASHES$HASH $FILE"
70+
done
71+
HASH_MATCHES=0
72+
MSG="$(git show -s --format=format:%B $1 | tail -n1)"
73+
74+
case "$MSG -" in
75+
"Tree-SHA512: $(echo "$FILE_HASHES" | sha512sum)")
76+
HASH_MATCHES=1;;
77+
esac
78+
79+
if [ "$HASH_MATCHES" = "0" ]; then
80+
echo "Tree-SHA512 did not match for commit $1" > /dev/stderr
81+
HAVE_FAILED=true
82+
return 1
83+
fi
84+
fi
85+
2886
local PARENTS
2987
PARENTS=$(git show -s --format=format:%P $1)
3088
for PARENT in $PARENTS; do
31-
if IS_SIGNED $PARENT; then
89+
if IS_SIGNED $PARENT $VERIFY_TREE $NO_SHA1; then
3290
return 0;
3391
fi
3492
break
@@ -50,7 +108,13 @@ else
50108
TEST_COMMIT="$1"
51109
fi
52110

53-
IS_SIGNED "$TEST_COMMIT"
111+
DO_CHECKOUT_TEST=0
112+
if [ x"$2" = "x--tree-checks" ]; then
113+
DO_CHECKOUT_TEST=1
114+
115+
fi
116+
117+
IS_SIGNED "$TEST_COMMIT" "$DO_CHECKOUT_TEST" 1
54118
RES=$?
55119
if [ "$RES" = 1 ]; then
56120
if ! "$HAVE_FAILED"; then

0 commit comments

Comments
 (0)