aboutsummaryrefslogtreecommitdiff
path: root/contrib/verify-commits/verify-commits.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/verify-commits/verify-commits.py')
-rwxr-xr-xcontrib/verify-commits/verify-commits.py49
1 files changed, 35 insertions, 14 deletions
diff --git a/contrib/verify-commits/verify-commits.py b/contrib/verify-commits/verify-commits.py
index 3825caf5de..f301964280 100755
--- a/contrib/verify-commits/verify-commits.py
+++ b/contrib/verify-commits/verify-commits.py
@@ -92,8 +92,10 @@ def main():
unclean_merge_allowed = f.read().splitlines()
with open(dirname + "/allow-incorrect-sha512-commits", "r", encoding="utf8") as f:
incorrect_sha512_allowed = f.read().splitlines()
+ with open(dirname + "/trusted-keys", "r", encoding="utf8") as f:
+ trusted_keys = f.read().splitlines()
- # Set commit and branch and set variables
+ # Set commit and variables
current_commit = args.commit
if ' ' in current_commit:
print("Commit must not contain spaces", file=sys.stderr)
@@ -102,7 +104,6 @@ def main():
no_sha1 = True
prev_commit = ""
initial_commit = current_commit
- branch = subprocess.check_output([GIT, 'show', '-s', '--format=%H', initial_commit]).decode('utf8').splitlines()[0]
# Iterate through commits
while True:
@@ -113,17 +114,41 @@ def main():
if current_commit == verified_root:
print('There is a valid path from "{}" to {} where all commits are signed!'.format(initial_commit, verified_root))
sys.exit(0)
- if current_commit == verified_sha512_root:
- if verify_tree:
+ else:
+ # Make sure this commit isn't older than trusted roots
+ check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_root, current_commit])
+ if check_root_older_res.returncode != 0:
+ print(f"\"{current_commit}\" predates the trusted root, stopping!")
+ sys.exit(0)
+
+ if verify_tree:
+ if current_commit == verified_sha512_root:
print("All Tree-SHA512s matched up to {}".format(verified_sha512_root), file=sys.stderr)
- verify_tree = False
- no_sha1 = False
+ verify_tree = False
+ no_sha1 = False
+ else:
+ # Skip the tree check if we are older than the trusted root
+ check_root_older_res = subprocess.run([GIT, "merge-base", "--is-ancestor", verified_sha512_root, current_commit])
+ if check_root_older_res.returncode != 0:
+ print(f"\"{current_commit}\" predates the trusted SHA512 root, disabling tree verification.")
+ verify_tree = False
+ no_sha1 = False
+
os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_SHA1'] = "0" if no_sha1 else "1"
- os.environ['BITCOIN_VERIFY_COMMITS_ALLOW_REVSIG'] = "1" if current_commit in revsig_allowed else "0"
+ allow_revsig = current_commit in revsig_allowed
# Check that the commit (and parents) was signed with a trusted key
- if subprocess.call([GIT, '-c', 'gpg.program={}/gpg.sh'.format(dirname), 'verify-commit', current_commit], stdout=subprocess.DEVNULL):
+ valid_sig = False
+ verify_res = subprocess.run([GIT, '-c', 'gpg.program={}/gpg.sh'.format(dirname), 'verify-commit', "--raw", current_commit], capture_output=True)
+ for line in verify_res.stderr.decode().splitlines():
+ if line.startswith("[GNUPG:] VALIDSIG "):
+ key = line.split(" ")[-1]
+ valid_sig = key in trusted_keys
+ elif (line.startswith("[GNUPG:] REVKEYSIG ") or line.startswith("[GNUPG:] EXPKEYSIG ")) and not allow_revsig:
+ valid_sig = False
+ break
+ if not valid_sig:
if prev_commit != "":
print("No parent of {} was signed with a trusted key!".format(prev_commit), file=sys.stderr)
print("Parents are:", file=sys.stderr)
@@ -153,15 +178,11 @@ def main():
allow_unclean = current_commit in unclean_merge_allowed
if len(parents) == 2 and check_merge and not allow_unclean:
current_tree = subprocess.check_output([GIT, 'show', '--format=%T', current_commit]).decode('utf8').splitlines()[0]
- subprocess.call([GIT, 'checkout', '--force', '--quiet', parents[0]])
- subprocess.call([GIT, 'merge', '--no-ff', '--quiet', '--no-gpg-sign', parents[1]], stdout=subprocess.DEVNULL)
- recreated_tree = subprocess.check_output([GIT, 'show', '--format=format:%T', 'HEAD']).decode('utf8').splitlines()[0]
+ recreated_tree = subprocess.check_output([GIT, "merge-tree", parents[0], parents[1]]).decode('utf8').splitlines()[0]
if current_tree != recreated_tree:
print("Merge commit {} is not clean".format(current_commit), file=sys.stderr)
- subprocess.call([GIT, 'diff', current_commit])
- subprocess.call([GIT, 'checkout', '--force', '--quiet', branch])
+ subprocess.call([GIT, 'diff', recreated_tree, current_tree])
sys.exit(1)
- subprocess.call([GIT, 'checkout', '--force', '--quiet', branch])
prev_commit = current_commit
current_commit = parents[0]