Skip to content

Conversation

@sipa
Copy link
Member

@sipa sipa commented Feb 27, 2017

This adds a SHA512 hash of the resulting merged tree to merge commit messages. Assuming gpg uses a sufficiently strong hash internally, this results in our gpg signed commits avoiding any potential SHA1 issues w.r.t. the commit's resulting contents (but NOT its history).

The hash can be verified by running git ls-tree --full-tree -r --name-only HEAD | LANG=C sort | xargs -n 1 sha512sum | sha512sum in the repository root.

@petertodd
Copy link
Contributor

Given how few lines of code this requires and how easy it is to independently calculate, concept ACK as a quick fix.

@da2ce7
Copy link

da2ce7 commented Feb 27, 2017

Creating a 'git-sha512-treehashes.txt' file in the root folder of the repo. That is a list of every sha512 tree hash for every merge commit (in this reop history).

Each new merge commit should append it's sha512-tree-hash to this file. This would make falsifying sha1 root hash far-harder as modifying any file will update the root-hash from two different locations.

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Feb 27, 2017 via email

Copy link
Contributor

@kallewoof kallewoof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK fa89670

intern.update(piece)
else:
break
fi.close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use with instead of open/close:

with open(f, 'rb') as fi:
    while True:
        piece = fi.read(65536)
        if piece:
            intern.update(piece)
        else:
            break

@petertodd
Copy link
Contributor

@TheBlueMatt The PGP signature on a git commit signs the entire commit object, including the message and thus SHA512 hash. So the SHA512 tree hash can be verified directly; you don't need another PGP signature.

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Feb 27, 2017 via email

@petertodd
Copy link
Contributor

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017 via email

@petertodd
Copy link
Contributor

@sipa Nope, that's simply not how git works. The commit object itself is what's piped to GnuPG, not just the hash of that object.

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017

@petertodd I'm aware. But GnuPG then takes a SHA1 hash of that. It's hardcoded by git to use SHA1, I believe.

@petertodd
Copy link
Contributor

petertodd commented Feb 27, 2017

@sipa GnuPG uses whatever hash algorithm you've told it to use; defaults used to be SHA1, but that's both easy to change, and IIRC the default is now SHA256. EDIT: Just checked with 1.4.18, default is now SHA256.

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017

@petertodd I don't think so (but I'd be glad to be wrong). Look at the actual data with git cat-file -p <commit>. It does not include the otherwise mandatory hash type line, so I assume gpg prepends that before verification. That can't work if it's anything but the default. git does not use detached signatures.

@petertodd
Copy link
Contributor

@sipa It's missing because it's not a clearsigned signature; it's an ascii encoded detached signature.

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017

Hmm, I read conflicting information. I hope I'm wrong.

@petertodd
Copy link
Contributor

@sipa Don't worry, you are wrong. :)

Like I said above, look at the git integration code I linked above from the OpenTimestamps client. Notably, the command line flags -bsau are passed to gpg by git when signing, which creates an ascii-encoded detached signature.

@dcousens
Copy link
Contributor

dcousens commented Feb 27, 2017

@petertodd
Copy link
Contributor

@dcousens They're talking about the equivalent of segwit vs how Bitcoin works now; it's not relevant to what we're talking about here.

@dcousens
Copy link
Contributor

dcousens commented Feb 27, 2017

@petertodd no worries, did git change since that SO question or was your comment noting that the GPG signing process used here (in bitcoin/bitcoin) is different?

FWIW, I also saw https://grimoire.ca/git/detached-sigs

@petertodd
Copy link
Contributor

@dcousens The "detached sigs" your links are referring to isn't the same thing as the "detached sigs" we're talking about above.

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017

Cool, so this is much more useful than I thought :)

@achow101
Copy link
Member

achow101 commented Feb 27, 2017

So as long as the merge commit signers use SHA512 (or something like that, maybe SHA256) for GPG this solution is essentially perfect (besides git upgrading to a new hash function).

And for those who care, this is where git calls gpg for signing.

@sipa sipa changed the title [RFC] Add a tree sha512 hash to merge commits Add a tree sha512 hash to merge commits Feb 27, 2017
@laanwj
Copy link
Member

laanwj commented Feb 27, 2017

I'm not sure how this works: git ls-tree --full-tree -r --name-only HEAD returns a list of filenames. Is it enough assurance to hash that, you don't need the file contents?

Travis fails are, as usual, unrelated.

@sipa
Copy link
Member Author

sipa commented Feb 27, 2017

I read in the actual files, and hash those, and then hash the result as like the result of sha512sum (look at the command line).

@achow101
Copy link
Member

@laanwj it does that command to grab the list of files. Then it opens each file in the list and hashes it.

@laanwj
Copy link
Member

laanwj commented Feb 27, 2017

I read in the actual files, and hash those, and then hash the result as like the result of sha512sum (look at the command line).

Oh, then things are alright again, thanks :)

Going to test this.

except subprocess.CalledProcessError as e:
printf("ERROR: Cannot update message.",file=stderr)
exit(4)
second_sha512 = tree_sha512sum()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the above call to tree_sha512sum() guarded by a try except clause and this one is not?

Anyway, I think the right place to put the second check would be verify-commits.sh.

@maflcko
Copy link
Member

maflcko commented Feb 27, 2017

Concept ACK

Copy link
Contributor

@jonasschnelli jonasschnelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK fa89670

@achow101
Copy link
Member

utACK fa89670

@TheBlueMatt
Copy link
Contributor

We should probably have some better handling for symlinks, no?

@sipa
Copy link
Member Author

sipa commented Feb 28, 2017

@TheBlueMatt I think that may be overkill, but ok... how would you construct something that's easily shell-verifiable?

@laanwj
Copy link
Member

laanwj commented Feb 28, 2017

We should probably have some better handling for symlinks, no?

What about just rejecting symlinks? We don't use them in this repository and probably shouldn't as not all OSes have that concept.

@TheBlueMatt
Copy link
Contributor

TheBlueMatt commented Feb 28, 2017 via email

@petertodd
Copy link
Contributor

ACK to rejecting symlinks.

We don't need to go overkill here and make this a scheme every project could adopt.

@laanwj
Copy link
Member

laanwj commented Mar 1, 2017

I'm just going to merge this - this is a nice and simple change that alleviates the direct worries about SHA1 compromise. More advanced things or functionality to reject symlinks can be added to the script later.

@laanwj laanwj merged commit fa89670 into bitcoin:master Mar 1, 2017
laanwj added a commit that referenced this pull request Mar 1, 2017
fa89670 Add SHA512 tree hash to merge commits (Pieter Wuille)

Tree-SHA512: 72321597336d3c4957719c8b907f258814b01499a82d2bc1e8c678b8825461d95f23b42ff6868a25725f4bfc3da24f7b12c058b45cbc7a7dfbf668888b68274e
@sipa sipa deleted the merge_sha512 branch June 23, 2017 00:38
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jan 23, 2019
fa89670 Add SHA512 tree hash to merge commits (Pieter Wuille)

Tree-SHA512: 72321597336d3c4957719c8b907f258814b01499a82d2bc1e8c678b8825461d95f23b42ff6868a25725f4bfc3da24f7b12c058b45cbc7a7dfbf668888b68274e
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.