aboutsummaryrefslogtreecommitdiff
path: root/contrib/verify-commits
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2017-02-27 14:13:39 -0500
committerMatt Corallo <git@bluematt.me>2017-03-04 09:41:15 -0500
commitd9c450ffb2a5a619ce11304f31427af9c9bf7a92 (patch)
tree5cd7cef12b36729e9061bdcca0fc8d30e5fb84af /contrib/verify-commits
parentbe908a69bf74a74a263bde14c310b397abe6776f (diff)
Verify Tree-SHA512s in merge commits, enforce sigs are not SHA1
Diffstat (limited to 'contrib/verify-commits')
-rwxr-xr-xcontrib/verify-commits/gpg.sh7
-rw-r--r--contrib/verify-commits/trusted-sha512-root-commit1
-rwxr-xr-xcontrib/verify-commits/verify-commits.sh68
3 files changed, 73 insertions, 3 deletions
diff --git a/contrib/verify-commits/gpg.sh b/contrib/verify-commits/gpg.sh
index 09ff237544..4df8bee3b3 100755
--- a/contrib/verify-commits/gpg.sh
+++ b/contrib/verify-commits/gpg.sh
@@ -8,7 +8,12 @@ VALID=false
REVSIG=false
IFS='
'
-for LINE in $(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null); do
+if [ "$BITCOIN_VERIFY_COMMITS_ALLOW_SHA1" = 1 ]; then
+ GPG_RES="$(echo "$INPUT" | gpg --trust-model always "$@" 2>/dev/null)"
+else
+ GPG_RES="$(echo "$INPUT" | gpg --trust-model always --weak-digest sha1 "$@" 2>/dev/null)"
+fi
+for LINE in $(echo "$GPG_RES"); do
case "$LINE" in
"[GNUPG:] VALIDSIG "*)
while read KEY; do
diff --git a/contrib/verify-commits/trusted-sha512-root-commit b/contrib/verify-commits/trusted-sha512-root-commit
new file mode 100644
index 0000000000..189dc215e3
--- /dev/null
+++ b/contrib/verify-commits/trusted-sha512-root-commit
@@ -0,0 +1 @@
+b00ba6251f71fa1edaabdf809514e1bc3c67862e
diff --git a/contrib/verify-commits/verify-commits.sh b/contrib/verify-commits/verify-commits.sh
index b2cebdf1a0..55eccf588a 100755
--- a/contrib/verify-commits/verify-commits.sh
+++ b/contrib/verify-commits/verify-commits.sh
@@ -9,7 +9,10 @@
DIR=$(dirname "$0")
[ "/${DIR#/}" != "$DIR" ] && DIR=$(dirname "$(pwd)/$0")
+echo "Using verify-commits data from ${DIR}"
+
VERIFIED_ROOT=$(cat "${DIR}/trusted-git-root")
+VERIFIED_SHA512_ROOT=$(cat "${DIR}/trusted-sha512-root-commit")
REVSIG_ALLOWED=$(cat "${DIR}/allow-revsig-commits")
HAVE_FAILED=false
@@ -17,18 +20,73 @@ IS_SIGNED () {
if [ $1 = $VERIFIED_ROOT ]; then
return 0;
fi
+
+ VERIFY_TREE=$2
+ NO_SHA1=$3
+ if [ $1 = $VERIFIED_SHA512_ROOT ]; then
+ if [ "$VERIFY_TREE" = "1" ]; then
+ echo "All Tree-SHA512s matched up to $VERIFIED_SHA512_ROOT" > /dev/stderr
+ fi
+ VERIFY_TREE=0
+ NO_SHA1=0
+ fi
+
+ if [ "$NO_SHA1" = "1" ]; then
+ export BITCOIN_VERIFY_COMMITS_ALLOW_SHA1=0
+ else
+ export BITCOIN_VERIFY_COMMITS_ALLOW_SHA1=1
+ fi
+
if [ "${REVSIG_ALLOWED#*$1}" != "$REVSIG_ALLOWED" ]; then
export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=1
else
export BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG=0
fi
+
if ! git -c "gpg.program=${DIR}/gpg.sh" verify-commit $1 > /dev/null 2>&1; then
return 1;
fi
+
+ if [ "$VERIFY_TREE" = 1 ]; then
+ IFS_CACHE="$IFS"
+ IFS='
+'
+ for LINE in $(git ls-tree --full-tree -r $1); do
+ case "$LINE" in
+ "12"*)
+ echo "Repo contains symlinks" > /dev/stderr
+ IFS="$IFS_CACHE"
+ return 1
+ ;;
+ esac
+ done
+ IFS="$IFS_CACHE"
+
+ FILE_HASHES=""
+ for FILE in $(git ls-tree --full-tree -r --name-only $1 | LANG=C sort); do
+ HASH=$(git cat-file blob $1:"$FILE" | sha512sum | { read FIRST OTHER; echo $FIRST; } )
+ [ "$FILE_HASHES" != "" ] && FILE_HASHES="$FILE_HASHES"$'\n'
+ FILE_HASHES="$FILE_HASHES$HASH $FILE"
+ done
+ HASH_MATCHES=0
+ MSG="$(git show -s --format=format:%B $1 | tail -n1)"
+
+ case "$MSG -" in
+ "Tree-SHA512: $(echo "$FILE_HASHES" | sha512sum)")
+ HASH_MATCHES=1;;
+ esac
+
+ if [ "$HASH_MATCHES" = "0" ]; then
+ echo "Tree-SHA512 did not match for commit $1" > /dev/stderr
+ HAVE_FAILED=true
+ return 1
+ fi
+ fi
+
local PARENTS
PARENTS=$(git show -s --format=format:%P $1)
for PARENT in $PARENTS; do
- if IS_SIGNED $PARENT; then
+ if IS_SIGNED $PARENT $VERIFY_TREE $NO_SHA1; then
return 0;
fi
break
@@ -50,7 +108,13 @@ else
TEST_COMMIT="$1"
fi
-IS_SIGNED "$TEST_COMMIT"
+DO_CHECKOUT_TEST=0
+if [ x"$2" = "x--tree-checks" ]; then
+ DO_CHECKOUT_TEST=1
+
+fi
+
+IS_SIGNED "$TEST_COMMIT" "$DO_CHECKOUT_TEST" 1
RES=$?
if [ "$RES" = 1 ]; then
if ! "$HAVE_FAILED"; then