Skip to content
This repository has been archived by the owner on Mar 20, 2019. It is now read-only.

Trustable releases #69

Open
hasufell opened this issue Mar 21, 2017 · 8 comments
Open

Trustable releases #69

hasufell opened this issue Mar 21, 2017 · 8 comments

Comments

@hasufell
Copy link

hasufell commented Mar 21, 2017

Git tag and git commit signing are useless, since they only sign non-blob objects which which refer to tree and blob objects via SHA1.

Releases should be crypto-signed imo. The easiest solution is probably:

  • provide a source tarball (git archive --prefix=inox-patchset-${tag}/ --format=tar.gz -o inox-patchset-${tag}.tar.gz ${tag}) since git tag based tarballs are not actually static
  • attach an SHA256 file always
  • sign both the SHA256 (gpg --armor --detach-sig ...) and the static tarball file

If you want something more fancy, you can try signify, which is used by libressl, but it doesn't work too well with github imo (makes more sense when you have a whole directory of releases).

@Eloston
Copy link
Contributor

Eloston commented Mar 21, 2017

Git tag and git commit signing are useless, since they only sign non-blob objects which which refer to tree and blob objects via SHA1.

I'm not understanding how this is useless. According to the Git Book, the blob contents are included in its hash, and tree objects are hashed with blob hashes. Are you saying there's some way to change the blob or tree contents without changing its hash?

@hasufell
Copy link
Author

I'll explain it in more detail.

See the git object model and how the objects are connected: http://shafiulazam.com/gitbook/1_the_git_object_model.html

With git commit/tag signing you sign an object that has no content. Only blobs objects hold the actual content. Your tag or commit object is connected with the blob object via the tree object. Neither the tree nor the blob objects are signed. All of these are connected via SHA1.

So you are effectively signing an SHA-1 Manifest file. SHA-1 has a proven collision: https://shattered.io/
To simplify (it's not that simple though), an attacker would only have to change the blob object and manage to keep the same hash. Ofc we're talking pre-image attack + a few pesky git details, but... this is already way too close. Cryptographers like Bruce Schneier have said for years that we should abandon SHA-1.

Specific to git and it's broken GPG signing, this problem was also discussed numerous times on the git mailing list:
https://public-inbox.org/git/CAPp-Vrb_n6z39RLHZ4AeUaBFiJfL3_xX8Utfq7+bTgzZrza58Q@mail.gmail.com/
https://public-inbox.org/git/[email protected]/

Git signed tags and signed commits are cryptographically insecure,
they're useless at the moment.

And even Linus himself said https://www.spinics.net/lists/git/msg09588.html

Signed tags fundamentally have to be re-signed.
[...]
[ The one exception: the "signed tags" security does depend on the hashes
being cryptographically strong. So again, breaking SHA-1 would not mean
that git stops working, but it would potentially mean that if you
don't trust your own private repository, the signed tag may no longer
protect you entirely ]

It has also been discussed on the gentoo mailing list when they switched from CVS to git.

You can also easily verify it yourself with git tools:

  1. create a signed tag
  2. show the raw object content via git cat-file tag <tag-name> (notice how this is signed)
  3. follow the SHA1 referenced object (most likely a commit object) and show it too git cat-file commit <commit-hash> => this could be signed, but doesn't have to necessarily, doesn't matter in the end
  4. now let's look at the tree object referenced in the commit: git cat-file tree <hash> and git ls-tree <hash> => nothing signed
  5. follow any blob object and show it too via git cat-file blob <hash> => see how it's the raw unsigned data in your repository that you want to protect

You can try all combinations of commit and tag signing. Tree objects and blob objects will never be signed and they are connected to signed tags and commits via SHA-1. As such, the weakest link is SHA-1 and an attacker doesn't need to attack GPG, but only SHA-1. That is a fundamentally broken cryptographic model.

You might also find http://gregoryszorc.com/blog/2017/02/28/mercurial,-sha-1,-and-trusting-version-control/#disqus_thread interesting and a new Commit signing plan of mercurial because of partly this exact problem https://www.mercurial-scm.org/wiki/CommitSigningPlan

@Eloston
Copy link
Contributor

Eloston commented Mar 21, 2017

Ah ok. The whole argument was resting upon the cryptographically-weak SHA-1. Alright then. Thanks for the well written explanation anyway.

@hasufell
Copy link
Author

Well, I had that lengthy explanation already written somewhere else, so I figured I'd sum it up instead of saying "because SHA-1" :P

@DragoonAethis
Copy link

GitHub announced yesterday they're now checking for SHA-1 collisions on all pushes. While signing itself would be good (since it proves the source's identity even if the files aren't downloaded from GitHub), it seems the aforementioned attack would be prohibitively expensive to perform now, if possible at all. (Plus, Git is now working towards the infrastructure required to dump SHA-1, which solves the problem entirely in a year or two.)

@hasufell
Copy link
Author

hasufell commented Mar 21, 2017

GitHub announced yesterday they're now checking for SHA-1 collisions on all pushes.

How's that relevant for an MITM attack on a user, performing a tarball download? The thing they want to defend against in that link is something different.

@gcarq
Copy link
Owner

gcarq commented Mar 22, 2017

Good idea, I'm definitly looking into that (but not for the 57.0.2987.98 release).

Besides the SHA-1 issue it would be also nice to have some sort of deterministic builds in the long term. (i.e.: gitian-building, TL;DR: "Gitian is the deterministic build process that is used to build the Bitcoin Core executables. It provides a way to be reasonably sure that the executables are really built from the source on GitHub.")

@hasufell
Copy link
Author

Well, static linking isn't probably within the scope and I'd argue against it.

Sounds more like https://reproducible-builds.org maybe?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants